|
@@ -1,9 +1,5 @@
|
|
|
-import inspect
|
|
|
|
|
import json
|
|
import json
|
|
|
-import os
|
|
|
|
|
import uuid
|
|
import uuid
|
|
|
-from functools import cached_property
|
|
|
|
|
-from pkgutil import ModuleInfo, get_importer
|
|
|
|
|
|
|
|
|
|
import django_rq
|
|
import django_rq
|
|
|
from django.conf import settings
|
|
from django.conf import settings
|
|
@@ -22,18 +18,15 @@ from django.utils.formats import date_format
|
|
|
from django.utils.translation import gettext as _
|
|
from django.utils.translation import gettext as _
|
|
|
from rest_framework.utils.encoders import JSONEncoder
|
|
from rest_framework.utils.encoders import JSONEncoder
|
|
|
|
|
|
|
|
-from core.choices import ManagedFileRootPathChoices
|
|
|
|
|
-from core.models import ManagedFile
|
|
|
|
|
from extras.choices import *
|
|
from extras.choices import *
|
|
|
from extras.conditions import ConditionSet
|
|
from extras.conditions import ConditionSet
|
|
|
from extras.constants import *
|
|
from extras.constants import *
|
|
|
-from extras.utils import FeatureQuery, image_upload, is_report, is_script
|
|
|
|
|
|
|
+from extras.utils import FeatureQuery, image_upload
|
|
|
from netbox.config import get_config
|
|
from netbox.config import get_config
|
|
|
from netbox.constants import RQ_QUEUE_DEFAULT
|
|
from netbox.constants import RQ_QUEUE_DEFAULT
|
|
|
from netbox.models import ChangeLoggedModel
|
|
from netbox.models import ChangeLoggedModel
|
|
|
from netbox.models.features import (
|
|
from netbox.models.features import (
|
|
|
- CloningMixin, CustomFieldsMixin, CustomLinksMixin, ExportTemplatesMixin, JobResultsMixin, SyncedDataMixin,
|
|
|
|
|
- TagsMixin, WebhooksMixin,
|
|
|
|
|
|
|
+ CloningMixin, CustomFieldsMixin, CustomLinksMixin, ExportTemplatesMixin, SyncedDataMixin, TagsMixin,
|
|
|
)
|
|
)
|
|
|
from utilities.querysets import RestrictedQuerySet
|
|
from utilities.querysets import RestrictedQuerySet
|
|
|
from utilities.rqworker import get_queue_for_model
|
|
from utilities.rqworker import get_queue_for_model
|
|
@@ -46,11 +39,7 @@ __all__ = (
|
|
|
'ImageAttachment',
|
|
'ImageAttachment',
|
|
|
'JobResult',
|
|
'JobResult',
|
|
|
'JournalEntry',
|
|
'JournalEntry',
|
|
|
- 'Report',
|
|
|
|
|
- 'ReportModule',
|
|
|
|
|
'SavedFilter',
|
|
'SavedFilter',
|
|
|
- 'Script',
|
|
|
|
|
- 'ScriptModule',
|
|
|
|
|
'Webhook',
|
|
'Webhook',
|
|
|
)
|
|
)
|
|
|
|
|
|
|
@@ -816,132 +805,3 @@ class ConfigRevision(models.Model):
|
|
|
@admin.display(boolean=True)
|
|
@admin.display(boolean=True)
|
|
|
def is_active(self):
|
|
def is_active(self):
|
|
|
return cache.get('config_version') == self.pk
|
|
return cache.get('config_version') == self.pk
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-#
|
|
|
|
|
-# Custom scripts & reports
|
|
|
|
|
-#
|
|
|
|
|
-
|
|
|
|
|
-class PythonModuleMixin:
|
|
|
|
|
-
|
|
|
|
|
- @property
|
|
|
|
|
- def path(self):
|
|
|
|
|
- return os.path.splitext(self.file_path)[0]
|
|
|
|
|
-
|
|
|
|
|
- def get_module_info(self):
|
|
|
|
|
- path = os.path.dirname(self.full_path)
|
|
|
|
|
- module_name = os.path.basename(self.path)
|
|
|
|
|
- return ModuleInfo(
|
|
|
|
|
- module_finder=get_importer(path),
|
|
|
|
|
- name=module_name,
|
|
|
|
|
- ispkg=False
|
|
|
|
|
- )
|
|
|
|
|
-
|
|
|
|
|
- def get_module(self):
|
|
|
|
|
- importer, module_name, _ = self.get_module_info()
|
|
|
|
|
- module = importer.find_module(module_name).load_module(module_name)
|
|
|
|
|
- return module
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-class Script(JobResultsMixin, WebhooksMixin, models.Model):
|
|
|
|
|
- """
|
|
|
|
|
- Dummy model used to generate permissions for custom scripts. Does not exist in the database.
|
|
|
|
|
- """
|
|
|
|
|
- class Meta:
|
|
|
|
|
- managed = False
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-class ScriptModuleManager(models.Manager.from_queryset(RestrictedQuerySet)):
|
|
|
|
|
-
|
|
|
|
|
- def get_queryset(self):
|
|
|
|
|
- return super().get_queryset().filter(file_root=ManagedFileRootPathChoices.SCRIPTS)
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-class ScriptModule(PythonModuleMixin, ManagedFile):
|
|
|
|
|
- """
|
|
|
|
|
- Proxy model for script module files.
|
|
|
|
|
- """
|
|
|
|
|
- objects = ScriptModuleManager()
|
|
|
|
|
-
|
|
|
|
|
- class Meta:
|
|
|
|
|
- proxy = True
|
|
|
|
|
-
|
|
|
|
|
- def get_absolute_url(self):
|
|
|
|
|
- return reverse('extras:script_list')
|
|
|
|
|
-
|
|
|
|
|
- @cached_property
|
|
|
|
|
- def scripts(self):
|
|
|
|
|
-
|
|
|
|
|
- def _get_name(cls):
|
|
|
|
|
- # For child objects in submodules use the full import path w/o the root module as the name
|
|
|
|
|
- return cls.full_name.split(".", maxsplit=1)[1]
|
|
|
|
|
-
|
|
|
|
|
- module = self.get_module()
|
|
|
|
|
- scripts = {}
|
|
|
|
|
- ordered = getattr(module, 'script_order', [])
|
|
|
|
|
-
|
|
|
|
|
- for cls in ordered:
|
|
|
|
|
- scripts[_get_name(cls)] = cls
|
|
|
|
|
- for name, cls in inspect.getmembers(module, is_script):
|
|
|
|
|
- if cls not in ordered:
|
|
|
|
|
- scripts[_get_name(cls)] = cls
|
|
|
|
|
-
|
|
|
|
|
- return scripts
|
|
|
|
|
-
|
|
|
|
|
- def save(self, *args, **kwargs):
|
|
|
|
|
- self.file_root = ManagedFileRootPathChoices.SCRIPTS
|
|
|
|
|
- return super().save(*args, **kwargs)
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-#
|
|
|
|
|
-# Reports
|
|
|
|
|
-#
|
|
|
|
|
-
|
|
|
|
|
-class Report(JobResultsMixin, WebhooksMixin, models.Model):
|
|
|
|
|
- """
|
|
|
|
|
- Dummy model used to generate permissions for reports. Does not exist in the database.
|
|
|
|
|
- """
|
|
|
|
|
- class Meta:
|
|
|
|
|
- managed = False
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-class ReportModuleManager(models.Manager.from_queryset(RestrictedQuerySet)):
|
|
|
|
|
-
|
|
|
|
|
- def get_queryset(self):
|
|
|
|
|
- return super().get_queryset().filter(file_root=ManagedFileRootPathChoices.REPORTS)
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-class ReportModule(PythonModuleMixin, ManagedFile):
|
|
|
|
|
- """
|
|
|
|
|
- Proxy model for report module files.
|
|
|
|
|
- """
|
|
|
|
|
- objects = ReportModuleManager()
|
|
|
|
|
-
|
|
|
|
|
- class Meta:
|
|
|
|
|
- proxy = True
|
|
|
|
|
-
|
|
|
|
|
- def get_absolute_url(self):
|
|
|
|
|
- return reverse('extras:report_list')
|
|
|
|
|
-
|
|
|
|
|
- @cached_property
|
|
|
|
|
- def reports(self):
|
|
|
|
|
-
|
|
|
|
|
- def _get_name(cls):
|
|
|
|
|
- # For child objects in submodules use the full import path w/o the root module as the name
|
|
|
|
|
- return cls.full_name.split(".", maxsplit=1)[1]
|
|
|
|
|
-
|
|
|
|
|
- module = self.get_module()
|
|
|
|
|
- reports = {}
|
|
|
|
|
- ordered = getattr(module, 'report_order', [])
|
|
|
|
|
-
|
|
|
|
|
- for cls in ordered:
|
|
|
|
|
- reports[_get_name(cls)] = cls
|
|
|
|
|
- for name, cls in inspect.getmembers(module, is_report):
|
|
|
|
|
- if cls not in ordered:
|
|
|
|
|
- reports[_get_name(cls)] = cls
|
|
|
|
|
-
|
|
|
|
|
- return reports
|
|
|
|
|
-
|
|
|
|
|
- def save(self, *args, **kwargs):
|
|
|
|
|
- self.file_root = ManagedFileRootPathChoices.REPORTS
|
|
|
|
|
- return super().save(*args, **kwargs)
|
|
|