import inspect import json import logging import os import traceback from datetime import timedelta import yaml from django import forms from django.conf import settings from django.core.validators import RegexValidator from django.db import transaction from django.utils import timezone from django.utils.functional import classproperty from django.utils.translation import gettext as _ from core.choices import JobStatusChoices from core.models import Job from extras.choices import LogLevelChoices from extras.models import ScriptModule, Script as ScriptModel from extras.signals import clear_events from ipam.formfields import IPAddressFormField, IPNetworkFormField from ipam.validators import MaxPrefixLengthValidator, MinPrefixLengthValidator, prefix_validator from utilities.exceptions import AbortScript, AbortTransaction from utilities.forms import add_blank_choice from utilities.forms.fields import DynamicModelChoiceField, DynamicModelMultipleChoiceField from .context_managers import event_tracking from .forms import ScriptForm from .utils import is_report __all__ = ( 'BaseScript', 'BooleanVar', 'ChoiceVar', 'FileVar', 'IntegerVar', 'IPAddressVar', 'IPAddressWithMaskVar', 'IPNetworkVar', 'MultiChoiceVar', 'MultiObjectVar', 'ObjectVar', 'Script', 'StringVar', 'TextVar', 'get_module_and_script', 'run_script', ) # # Script variables # class ScriptVariable: """ Base model for script variables """ form_field = forms.CharField def __init__(self, label='', description='', default=None, required=True, widget=None): # Initialize field attributes if not hasattr(self, 'field_attrs'): self.field_attrs = {} if label: self.field_attrs['label'] = label if description: self.field_attrs['help_text'] = description if default: self.field_attrs['initial'] = default if widget: self.field_attrs['widget'] = widget self.field_attrs['required'] = required def as_field(self): """ Render the variable as a Django form field. """ form_field = self.form_field(**self.field_attrs) if not isinstance(form_field.widget, forms.CheckboxInput): if form_field.widget.attrs and 'class' in form_field.widget.attrs.keys(): form_field.widget.attrs['class'] += ' form-control' else: form_field.widget.attrs['class'] = 'form-control' return form_field class StringVar(ScriptVariable): """ 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 TextVar(ScriptVariable): """ Free-form text data. Renders as a