mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-23 04:22:01 -06:00
Add options for script vars; include script output
This commit is contained in:
parent
a25a27f31f
commit
9d054fb345
@ -4,27 +4,37 @@ import pkgutil
|
||||
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.core.validators import RegexValidator
|
||||
|
||||
from .constants import LOG_DEFAULT, LOG_FAILURE, LOG_INFO, LOG_SUCCESS, LOG_WARNING
|
||||
from .forms import ScriptForm
|
||||
|
||||
|
||||
class OptionalBooleanField(forms.BooleanField):
|
||||
required = False
|
||||
|
||||
|
||||
#
|
||||
# Script variables
|
||||
#
|
||||
|
||||
class ScriptVariable:
|
||||
"""
|
||||
Base model for script variables
|
||||
"""
|
||||
form_field = forms.CharField
|
||||
|
||||
def __init__(self, label='', description=''):
|
||||
def __init__(self, label='', description='', default=None, required=True):
|
||||
|
||||
# Default field attributes
|
||||
if not hasattr(self, 'field_attrs'):
|
||||
self.field_attrs = {}
|
||||
self.field_attrs = {
|
||||
'help_text': description,
|
||||
'required': required
|
||||
}
|
||||
if label:
|
||||
self.field_attrs['label'] = label
|
||||
if description:
|
||||
self.field_attrs['help_text'] = description
|
||||
if default:
|
||||
self.field_attrs['initial'] = default
|
||||
|
||||
def as_field(self):
|
||||
"""
|
||||
@ -34,26 +44,62 @@ class ScriptVariable:
|
||||
|
||||
|
||||
class StringVar(ScriptVariable):
|
||||
pass
|
||||
"""
|
||||
Character string representation. Can enforce minimum/maximum length and/or regex validation.
|
||||
"""
|
||||
def __init__(self, min_length=None, max_length=None, regex=None, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# Optional minimum/maximum lengths
|
||||
if min_length:
|
||||
self.field_attrs['min_length'] = min_length
|
||||
if max_length:
|
||||
self.field_attrs['max_length'] = max_length
|
||||
|
||||
# Optional regular expression validation
|
||||
if regex:
|
||||
self.field_attrs['validators'] = [
|
||||
RegexValidator(
|
||||
regex=regex,
|
||||
message='Invalid value. Must match regex: {}'.format(regex),
|
||||
code='invalid'
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
class IntegerVar(ScriptVariable):
|
||||
"""
|
||||
Integer representation. Can enforce minimum/maximum values.
|
||||
"""
|
||||
form_field = forms.IntegerField
|
||||
|
||||
def __init__(self, min_value=None, max_value=None, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# Optional minimum/maximum values
|
||||
if min_value:
|
||||
self.field_attrs['min_value'] = min_value
|
||||
if max_value:
|
||||
self.field_attrs['max_value'] = max_value
|
||||
|
||||
|
||||
class BooleanVar(ScriptVariable):
|
||||
form_field = forms.BooleanField
|
||||
field_attrs = {
|
||||
'required': False
|
||||
}
|
||||
"""
|
||||
Boolean representation (true/false). Renders as a checkbox.
|
||||
"""
|
||||
form_field = OptionalBooleanField
|
||||
|
||||
|
||||
class ObjectVar(ScriptVariable):
|
||||
"""
|
||||
NetBox object representation. The provided QuerySet will determine the choices available.
|
||||
"""
|
||||
form_field = forms.ModelChoiceField
|
||||
|
||||
def __init__(self, queryset, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# Queryset for field choices
|
||||
self.field_attrs['queryset'] = queryset
|
||||
|
||||
|
||||
@ -61,7 +107,6 @@ class Script:
|
||||
"""
|
||||
Custom scripts inherit this object.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
|
||||
# Initiate the log
|
||||
@ -80,7 +125,7 @@ class Script:
|
||||
# TODO: This should preserve var ordering
|
||||
return inspect.getmembers(self, is_variable)
|
||||
|
||||
def run(self, context):
|
||||
def run(self, data):
|
||||
raise NotImplementedError("The script must define a run() method.")
|
||||
|
||||
def as_form(self, data=None):
|
||||
|
@ -396,14 +396,16 @@ class ScriptView(LoginRequiredMixin, View):
|
||||
|
||||
script = self._get_script(module, name)
|
||||
form = script.as_form(request.POST)
|
||||
output = None
|
||||
|
||||
if form.is_valid():
|
||||
|
||||
with transaction.atomic():
|
||||
script.run(form.cleaned_data)
|
||||
output = script.run(form.cleaned_data)
|
||||
|
||||
return render(request, 'extras/script.html', {
|
||||
'module': module,
|
||||
'script': script,
|
||||
'form': form,
|
||||
'output': output,
|
||||
})
|
||||
|
@ -21,6 +21,9 @@
|
||||
<li role="presentation" class="active">
|
||||
<a href="#run" role="tab" data-toggle="tab" class="active">Run</a>
|
||||
</li>
|
||||
<li role="presentation"{% if not output %} class="disabled"{% endif %}>
|
||||
<a href="#output" role="tab" data-toggle="tab">Output</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a href="#source" role="tab" data-toggle="tab">Source</a>
|
||||
</li>
|
||||
@ -69,6 +72,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="output">
|
||||
<pre>{{ output }}</pre>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="source">
|
||||
<strong>{{ script.filename }}</strong>
|
||||
<pre>{{ script.source }}</pre>
|
||||
|
Loading…
Reference in New Issue
Block a user