From ece5b4635e13866e8aafca9fdbbd667335c18bb5 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 6 Feb 2024 16:38:17 -0500 Subject: [PATCH] Reformat script job data (log, output, tests) --- netbox/extras/scripts.py | 61 ++++----- netbox/extras/views.py | 34 ++--- .../extras/htmx/legacy_report_result.html | 81 ----------- .../extras/htmx/legacy_script_result.html | 58 -------- .../templates/extras/htmx/script_result.html | 129 ++++++++++++------ netbox/templates/extras/script_result.html | 8 +- 6 files changed, 129 insertions(+), 242 deletions(-) delete mode 100644 netbox/templates/extras/htmx/legacy_report_result.html delete mode 100644 netbox/templates/extras/htmx/legacy_script_result.html diff --git a/netbox/extras/scripts.py b/netbox/extras/scripts.py index 3e914e5ac..5c87483a4 100644 --- a/netbox/extras/scripts.py +++ b/netbox/extras/scripts.py @@ -273,10 +273,11 @@ class BaseScript: pass def __init__(self): - self._logs = {} - self._failed = False - self._current_method = '' - self._output = '' + self.messages = [] # Primary script log + self.tests = {} # Mapping of logs for test methods + self.output = '' + self.failed = False + self._current_method = '' # Tracks the current test method being run (if any) # Initiate the log self.logger = logging.getLogger(f"netbox.scripts.{self.__module__}.{self.__class__.__name__}") @@ -285,25 +286,15 @@ class BaseScript: self.request = None # Compile test methods and initialize results skeleton - self._logs[''] = { - LogLevelChoices.LOG_SUCCESS: 0, - LogLevelChoices.LOG_INFO: 0, - LogLevelChoices.LOG_WARNING: 0, - LogLevelChoices.LOG_FAILURE: 0, - 'log': [], - } - test_methods = [] for method in dir(self): if method.startswith('test_') and callable(getattr(self, method)): - test_methods.append(method) - self._logs[method] = { + self.tests[method] = { LogLevelChoices.LOG_SUCCESS: 0, LogLevelChoices.LOG_INFO: 0, LogLevelChoices.LOG_WARNING: 0, LogLevelChoices.LOG_FAILURE: 0, 'log': [], } - self.test_methods = test_methods def __str__(self): return self.name @@ -448,10 +439,10 @@ class BaseScript: if level not in LogLevelChoices.values(): raise ValueError(f"Invalid logging level: {level}") - if message: + # A test method is currently active, so log the message using legacy Report logging + if self._current_method: - # Record to the script's log - self._logs[self._current_method]['log'].append(( + self.tests[self._current_method]['log'].append(( timezone.now().isoformat(), level, str(obj) if obj else None, @@ -459,19 +450,22 @@ class BaseScript: str(message), )) + # Increment the event counter for this level + if level in self.tests[self._current_method]: + self.tests[self._current_method][level] += 1 + + elif message: + + # Record to the script's log + self.messages.append( + (level, str(message)) + ) + # Record to the system log if obj: message = f"{obj}: {message}" self.logger.log(LogLevelChoices.SYSTEM_LEVELS[level], message) - # Increment the event counter for this level if applicable - if level in self._logs[self._current_method]: - self._logs[self._current_method][level] += 1 - - # For individual test methods, increment the global counter as well - if self._current_method: - self._logs[''][level] += 1 - def log_debug(self, message, obj=None): self._log(message, obj, level=LogLevelChoices.LOG_DEBUG) @@ -486,7 +480,7 @@ class BaseScript: def log_failure(self, message, obj=None): self._log(message, obj, level=LogLevelChoices.LOG_FAILURE) - self._failed = True + self.failed = True # # Convenience functions @@ -528,7 +522,7 @@ class BaseScript: self.logger.info(f"Running report") try: - for method_name in self.test_methods: + for method_name in self.tests: self._current_method = method_name test_method = getattr(self, method_name) test_method() @@ -606,11 +600,12 @@ def run_script(data, job, request=None, commit=True, **kwargs): script.request = request def set_job_data(script): - logs = script._logs job.data = { - 'logs': logs, - 'output': script._output, + 'log': script.messages, + 'output': script.output, + 'tests': script.tests, } + return job def _run_script(): @@ -621,7 +616,7 @@ def run_script(data, job, request=None, commit=True, **kwargs): try: try: with transaction.atomic(): - script._output = script.run(data, commit) + script.output = script.run(data, commit) if not commit: raise AbortTransaction() except AbortTransaction: @@ -635,7 +630,7 @@ def run_script(data, job, request=None, commit=True, **kwargs): if request: clear_events.send(request) job = set_job_data(script) - if script._failed: + if script.failed: logger.warning(f"Script failed") job.terminate(status=JobStatusChoices.STATUS_FAILED) else: diff --git a/netbox/extras/views.py b/netbox/extras/views.py index b4f87e633..de65d64f9 100644 --- a/netbox/extras/views.py +++ b/netbox/extras/views.py @@ -1153,32 +1153,28 @@ class ScriptResultView(ContentTypePermissionRequiredMixin, View): module = job.object script = module.scripts[job.name]() - legacy_script = False - legacy_report = False - if job.data and ('logs' not in job.data): - if 'log' in job.data: - legacy_script = True - else: - legacy_report = True + context = { + 'script': script, + 'job': job, + } + if job.data and 'log' in job.data: + # Script + context['tests'] = job.data.get('tests', {}) + elif job.data: + # Legacy Report + context['tests'] = { + name: data for name, data in job.data.items() + if name.startswith('test_') + } # If this is an HTMX request, return only the result HTML if request.htmx: - response = render(request, 'extras/htmx/script_result.html', { - 'script': script, - 'job': job, - 'legacy_script': legacy_script, - 'legacy_report': legacy_report, - }) + response = render(request, 'extras/htmx/script_result.html', context) if job.completed or not job.started: response.status_code = 286 return response - return render(request, 'extras/script_result.html', { - 'script': script, - 'job': job, - 'legacy_script': legacy_script, - 'legacy_report': legacy_report, - }) + return render(request, 'extras/script_result.html', context) # diff --git a/netbox/templates/extras/htmx/legacy_report_result.html b/netbox/templates/extras/htmx/legacy_report_result.html deleted file mode 100644 index e6b6caf73..000000000 --- a/netbox/templates/extras/htmx/legacy_report_result.html +++ /dev/null @@ -1,81 +0,0 @@ -{% load humanize %} -{% load helpers %} -{% load i18n %} - -

- {% if job.started %} - {% trans "Started" %}: {{ job.started|annotated_date }} - {% elif job.scheduled %} - {% trans "Scheduled for" %}: {{ job.scheduled|annotated_date }} ({{ job.scheduled|naturaltime }}) - {% else %} - {% trans "Created" %}: {{ job.created|annotated_date }} - {% endif %} - {% if job.completed %} - {% trans "Duration" %}: {{ job.duration }} - {% endif %} - {% badge job.get_status_display job.get_status_color %} -

-{% if job.completed %} -
-
{% trans "Report Methods" %}
-
- - {% for method, data in job.data.items %} - - - - - {% endfor %} -
{{ method }} - {{ data.success }} - {{ data.info }} - {{ data.warning }} - {{ data.failure }} -
-
-
-
-
{% trans "Report Results" %}
-
- - - - - - - - - - - {% for method, data in job.data.items %} - - - - {% for time, level, obj, url, message in data.log %} - - - - - - - {% endfor %} - {% endfor %} - -
{% trans "Time" %}{% trans "Level" %}{% trans "Object" %}{% trans "Message" %}
- {{ method }} -
{{ time }} - - - {% if obj and url %} - {{ obj }} - {% elif obj %} - {{ obj }} - {% else %} - {{ ''|placeholder }} - {% endif %} - {{ message|markdown }}
-
-
-{% elif job.started %} - {% include 'extras/inc/result_pending.html' %} -{% endif %} diff --git a/netbox/templates/extras/htmx/legacy_script_result.html b/netbox/templates/extras/htmx/legacy_script_result.html deleted file mode 100644 index ddc9b05f6..000000000 --- a/netbox/templates/extras/htmx/legacy_script_result.html +++ /dev/null @@ -1,58 +0,0 @@ -{% load humanize %} -{% load helpers %} -{% load log_levels %} -{% load i18n %} - -

- {% if job.started %} - {% trans "Started" %}: {{ job.started|annotated_date }} - {% elif job.scheduled %} - {% trans "Scheduled for" %}: {{ job.scheduled|annotated_date }} ({{ job.scheduled|naturaltime }}) - {% else %} - {% trans "Created" %}: {{ job.created|annotated_date }} - {% endif %} - {% if job.completed %} - {% trans "Duration" %}: {{ job.duration }} - {% endif %} - {% badge job.get_status_display job.get_status_color %} -

-{% if job.completed %} -
-
{% trans "Script Log" %}
-
- - - - - - - {% for log in job.data.log %} - - - - - - {% empty %} - - - - {% endfor %} -
{% trans "Line" %}{% trans "Level" %}{% trans "Message" %}
{{ forloop.counter }}{% log_level log.status %}{{ log.message|markdown }}
- {% trans "No log output" %} -
-
- {% if execution_time %} - - {% endif %} -
-

{% trans "Output" %}

- {% if job.data.output %} -
{{ job.data.output }}
- {% else %} -

{% trans "None" %}

- {% endif %} -{% elif job.started %} - {% include 'extras/inc/result_pending.html' %} -{% endif %} diff --git a/netbox/templates/extras/htmx/script_result.html b/netbox/templates/extras/htmx/script_result.html index f27672d10..70988f1f0 100644 --- a/netbox/templates/extras/htmx/script_result.html +++ b/netbox/templates/extras/htmx/script_result.html @@ -1,5 +1,6 @@ {% load humanize %} {% load helpers %} +{% load log_levels %} {% load i18n %}

@@ -16,59 +17,99 @@ {% badge job.get_status_display job.get_status_color %}

{% if job.completed %} -
-
{% trans "Script Methods" %}
- - {% for method, data in job.data.logs.items %} +
+
{% trans "Script Log" %}
+
+ + + + + + {% for log in job.data.log %} - - + + + + {% empty %} + + {% endfor %}
{% trans "Line" %}{% trans "Level" %}{% trans "Message" %}
{{ method }} - {{ data.success }} - {{ data.info }} - {{ data.warning }} - {{ data.failure }} + {{ forloop.counter }}{% log_level log.status %}{{ log.message|markdown }}
+ {% trans "No log output" %}
+ {% if execution_time %} + + {% endif %}
-

{% trans "Script Results" %}

+

{% trans "Output" %}

+ {% if job.data.output %} +
{{ job.data.output }}
+ {% else %} +

{% trans "None" %}

+ {% endif %} - {% for method, data in job.data.logs.items %} -
-
{{ method }}
- - - - - - - - - - - {% for time, level, obj, url, message in data.log %} - - - - - + {% if tests %} +
+
{% trans "Report Summary" %}
+
{% trans "Time" %}{% trans "Level" %}{% trans "Object" %}{% trans "Message" %}
{{ time }} - - - {% if obj and url %} - {{ obj }} - {% elif obj %} - {{ obj }} - {% else %} - {{ ''|placeholder }} - {% endif %} - {{ message|markdown }}
+ {% for test, data in tests.items %} + + + + + {% endfor %} +
{{ test }} + {{ data.success }} + {{ data.info }} + {{ data.warning }} + {{ data.failure }} +
+
+
+
{% trans "Report Results" %}
+ + + + + + + + + + + {% for test, data in tests.items %} + + + {% for time, level, obj, url, message in data.log %} + + + + + + + {% endfor %} {% endfor %} - -
{% trans "Time" %}{% trans "Level" %}{% trans "Object" %}{% trans "Message" %}
+ {{ test }} +
{{ time }} + + + {% if obj and url %} + {{ obj }} + {% elif obj %} + {{ obj }} + {% else %} + {{ ''|placeholder }} + {% endif %} + {{ message|markdown }}
-
- {% endfor %} + + + + {% endif %} {% elif job.started %} {% include 'extras/inc/result_pending.html' %} {% endif %} diff --git a/netbox/templates/extras/script_result.html b/netbox/templates/extras/script_result.html index 02a01149c..985c58d63 100644 --- a/netbox/templates/extras/script_result.html +++ b/netbox/templates/extras/script_result.html @@ -44,13 +44,7 @@
- {% if legacy_script %} - {% include 'extras/htmx/legacy_script_result.html' %} - {% elif legacy_report %} - {% include 'extras/htmx/legacy_report_result.html' %} - {% else %} - {% include 'extras/htmx/script_result.html' %} - {% endif %} + {% include 'extras/htmx/script_result.html' %}