Beispiel #1
0
class RelationshipForm(BootstrapMixin, forms.ModelForm):

    slug = SlugField()
    source_type = forms.ModelChoiceField(
        queryset=ContentType.objects.filter(
            FeatureQuery("relationships").get_query()).order_by(
                "app_label", "model"),
        help_text="The source object type to which this relationship applies.",
    )
    source_filter = JSONField(
        required=False,
        help_text=
        "Queryset filter matching the applicable source objects of the selected type.<br>"
        'Enter in <a href="https://json.org/">JSON</a> format.',
    )
    destination_type = forms.ModelChoiceField(
        queryset=ContentType.objects.filter(
            FeatureQuery("relationships").get_query()).order_by(
                "app_label", "model"),
        help_text=
        "The destination object type to which this relationship applies.",
    )
    destination_filter = JSONField(
        required=False,
        help_text=
        "Queryset filter matching the applicable destination objects of the selected type.<br>"
        'Enter in <a href="https://json.org/">JSON</a> format.',
    )

    class Meta:
        model = Relationship
        fields = [
            "name",
            "slug",
            "description",
            "type",
            "source_type",
            "source_label",
            "source_hidden",
            "source_filter",
            "destination_type",
            "destination_label",
            "destination_hidden",
            "destination_filter",
        ]

    def save(self, commit=True):

        # TODO add support for owner when a CR is created in the UI
        obj = super().save(commit)

        return obj
Beispiel #2
0
class SecretForm(BootstrapMixin, CustomFieldModelForm, RelationshipModelForm):
    """Create/update form for `Secret` objects."""

    slug = SlugField()

    provider = forms.ChoiceField(choices=provider_choices,
                                 widget=StaticSelect2())

    parameters = JSONField(
        help_text=
        'Enter parameters in <a href="https://json.org/">JSON</a> format.')

    tags = DynamicModelMultipleChoiceField(queryset=Tag.objects.all(),
                                           required=False)

    class Meta:
        model = Secret
        fields = [
            "name",
            "slug",
            "description",
            "provider",
            "parameters",
            "tags",
        ]
Beispiel #3
0
class ConfigContextForm(BootstrapMixin, forms.ModelForm):
    regions = DynamicModelMultipleChoiceField(queryset=Region.objects.all(), required=False)
    sites = DynamicModelMultipleChoiceField(queryset=Site.objects.all(), required=False)
    roles = DynamicModelMultipleChoiceField(queryset=DeviceRole.objects.all(), required=False)
    device_types = DynamicModelMultipleChoiceField(queryset=DeviceType.objects.all(), required=False)
    platforms = DynamicModelMultipleChoiceField(queryset=Platform.objects.all(), required=False)
    cluster_groups = DynamicModelMultipleChoiceField(queryset=ClusterGroup.objects.all(), required=False)
    clusters = DynamicModelMultipleChoiceField(queryset=Cluster.objects.all(), required=False)
    tenant_groups = DynamicModelMultipleChoiceField(queryset=TenantGroup.objects.all(), required=False)
    tenants = DynamicModelMultipleChoiceField(queryset=Tenant.objects.all(), required=False)
    tags = DynamicModelMultipleChoiceField(queryset=Tag.objects.all(), required=False)
    data = JSONField(label="")

    class Meta:
        model = ConfigContext
        fields = (
            "name",
            "weight",
            "description",
            "schema",
            "is_active",
            "regions",
            "sites",
            "roles",
            "device_types",
            "platforms",
            "cluster_groups",
            "clusters",
            "tenant_groups",
            "tenants",
            "tags",
            "data",
        )
Beispiel #4
0
class ConfigContextSchemaForm(BootstrapMixin, forms.ModelForm):
    data_schema = JSONField(label="")
    slug = SlugField()

    class Meta:
        model = ConfigContextSchema
        fields = (
            "name",
            "slug",
            "description",
            "data_schema",
        )
Beispiel #5
0
class LocalContextModelForm(forms.ModelForm):
    local_context_schema = DynamicModelChoiceField(
        queryset=ConfigContextSchema.objects.all(), required=False)
    local_context_data = JSONField(required=False, label="")
Beispiel #6
0
class VirtualMachineForm(BootstrapMixin, TenancyForm, CustomFieldModelForm,
                         RelationshipModelForm):
    cluster_group = DynamicModelChoiceField(
        queryset=ClusterGroup.objects.all(),
        required=False,
        null_option="None",
        initial_params={"clusters": "$cluster"},
    )
    cluster = DynamicModelChoiceField(
        queryset=Cluster.objects.all(),
        query_params={"group_id": "$cluster_group"})
    role = DynamicModelChoiceField(
        queryset=DeviceRole.objects.all(),
        required=False,
        query_params={"vm_role": "True"},
    )
    platform = DynamicModelChoiceField(queryset=Platform.objects.all(),
                                       required=False)
    local_context_data = JSONField(required=False, label="")
    tags = DynamicModelMultipleChoiceField(queryset=Tag.objects.all(),
                                           required=False)

    class Meta:
        model = VirtualMachine
        fields = [
            "name",
            "status",
            "cluster_group",
            "cluster",
            "role",
            "tenant_group",
            "tenant",
            "platform",
            "primary_ip4",
            "primary_ip6",
            "vcpus",
            "memory",
            "disk",
            "comments",
            "tags",
            "local_context_data",
        ]
        help_texts = {
            "local_context_data":
            "Local config context data overwrites all sources contexts in the final rendered "
            "config context",
        }
        widgets = {
            "primary_ip4": StaticSelect2(),
            "primary_ip6": StaticSelect2(),
        }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        if self.instance.present_in_database:

            # Compile list of choices for primary IPv4 and IPv6 addresses
            for family in [4, 6]:
                ip_choices = [(None, "---------")]

                # Gather PKs of all interfaces belonging to this VM
                interface_ids = self.instance.interfaces.values_list("pk",
                                                                     flat=True)

                # Collect interface IPs
                interface_ips = IPAddress.objects.ip_family(family).filter(
                    assigned_object_type=ContentType.objects.get_for_model(
                        VMInterface),
                    assigned_object_id__in=interface_ids,
                )
                if interface_ips:
                    ip_list = [(ip.id, f"{ip.address} ({ip.assigned_object})")
                               for ip in interface_ips]
                    ip_choices.append(("Interface IPs", ip_list))
                # Collect NAT IPs
                nat_ips = (IPAddress.objects.prefetch_related(
                    "nat_inside").ip_family(family).filter(
                        nat_inside__assigned_object_type=ContentType.objects.
                        get_for_model(VMInterface),
                        nat_inside__assigned_object_id__in=interface_ids,
                    ))
                if nat_ips:
                    ip_list = [(ip.id, f"{ip.address} (NAT)")
                               for ip in nat_ips]
                    ip_choices.append(("NAT IPs", ip_list))
                self.fields["primary_ip{}".format(family)].choices = ip_choices

        else:

            # An object that doesn't exist yet can't have any IPs assigned to it
            self.fields["primary_ip4"].choices = []
            self.fields["primary_ip4"].widget.attrs["readonly"] = True
            self.fields["primary_ip6"].choices = []
            self.fields["primary_ip6"].widget.attrs["readonly"] = True
Beispiel #7
0
    def to_form_field(self,
                      set_initial=True,
                      enforce_required=True,
                      for_csv_import=False,
                      simple_json_filter=False):
        """
        Return a form field suitable for setting a CustomField's value for an object.

        set_initial: Set initial date for the field. This should be False when generating a field for bulk editing.
        enforce_required: Honor the value of CustomField.required. Set to False for filtering/bulk editing.
        for_csv_import: Return a form field suitable for bulk import of objects in CSV format.
        simple_json_filter: Return a TextInput widget for JSON filtering instead of the default TextArea widget.
        """
        initial = self.default if set_initial else None
        required = self.required if enforce_required else False

        # Integer
        if self.type == CustomFieldTypeChoices.TYPE_INTEGER:
            field = forms.IntegerField(
                required=required,
                initial=initial,
                min_value=self.validation_minimum,
                max_value=self.validation_maximum,
            )

        # Boolean
        elif self.type == CustomFieldTypeChoices.TYPE_BOOLEAN:
            choices = (
                (None, "---------"),
                (True, "True"),
                (False, "False"),
            )
            field = forms.NullBooleanField(
                required=required,
                initial=initial,
                widget=StaticSelect2(choices=choices),
            )

        # Date
        elif self.type == CustomFieldTypeChoices.TYPE_DATE:
            field = forms.DateField(required=required,
                                    initial=initial,
                                    widget=DatePicker())

        # URL
        elif self.type == CustomFieldTypeChoices.TYPE_URL:
            field = LaxURLField(required=required, initial=initial)

        # Text
        elif self.type == CustomFieldTypeChoices.TYPE_TEXT:
            field = forms.CharField(max_length=255,
                                    required=required,
                                    initial=initial)
            if self.validation_regex:
                field.validators = [
                    RegexValidator(
                        regex=self.validation_regex,
                        message=mark_safe(
                            f"Values must match this regex: <code>{self.validation_regex}</code>"
                        ),
                    )
                ]

        # JSON
        elif self.type == CustomFieldTypeChoices.TYPE_JSON:

            if simple_json_filter:
                field = JSONField(encoder=DjangoJSONEncoder,
                                  required=required,
                                  initial=None,
                                  widget=TextInput)
            else:
                field = JSONField(encoder=DjangoJSONEncoder,
                                  required=required,
                                  initial=initial)

        # Select or Multi-select
        else:
            choices = [(cfc.value, cfc.value) for cfc in self.choices.all()]
            default_choice = self.choices.filter(value=self.default).first()

            if not required or default_choice is None:
                choices = add_blank_choice(choices)

            # Set the initial value to the first available choice (if any)
            if set_initial and default_choice:
                initial = default_choice.value

            if self.type == CustomFieldTypeChoices.TYPE_SELECT:
                field_class = CSVChoiceField if for_csv_import else forms.ChoiceField
                field = field_class(
                    choices=choices,
                    required=required,
                    initial=initial,
                    widget=StaticSelect2(),
                )
            else:
                field_class = CSVMultipleChoiceField if for_csv_import else forms.MultipleChoiceField
                field = field_class(choices=choices,
                                    required=required,
                                    initial=initial,
                                    widget=StaticSelect2Multiple())

        field.model = self
        field.label = str(self)

        if self.description:
            # Avoid script injection and similar attacks! Output HTML but only accept Markdown as input
            field.help_text = render_markdown(self.description)

        return field