text: from django import forms
  from django.contrib.contenttypes.models import ContentType
  
  from dcim.models import Device, Interface, Location, Rack, Region, Site, SiteGroup
  from extras.forms import CustomFieldModelForm
  from extras.models import Tag
  from ipam.constants import *
  from ipam.models import *
  from tenancy.forms import TenancyForm
  from utilities.forms import (
      BootstrapMixin, ContentTypeChoiceField, DatePicker, DynamicModelChoiceField, DynamicModelMultipleChoiceField,
      NumericArrayField, SlugField, StaticSelect, StaticSelectMultiple,
  )
  from virtualization.models import Cluster, ClusterGroup, VirtualMachine, VMInterface
  
  __all__ = (
      'AggregateForm',
      'IPAddressAssignForm',
      'IPAddressBulkAddForm',
      'IPAddressForm',
      'IPRangeForm',
      'PrefixForm',
      'RIRForm',
      'RoleForm',
      'RouteTargetForm',
      'ServiceForm',
      'VLANForm',
      'VLANGroupForm',
      'VRFForm',
  )
  
  
  class VRFForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
      import_targets = DynamicModelMultipleChoiceField(
          queryset=RouteTarget.objects.all(),
          required=False
      )
      export_targets = DynamicModelMultipleChoiceField(
          queryset=RouteTarget.objects.all(),
          required=False
      )
      tags = DynamicModelMultipleChoiceField(
          queryset=Tag.objects.all(),
          required=False
      )
  
      class Meta:
          model = VRF
          fields = [
              'name', 'rd', 'enforce_unique', 'description', 'import_targets', 'export_targets', 'tenant_group', 'tenant',
              'tags',
          ]
          fieldsets = (
              ('VRF', ('name', 'rd', 'enforce_unique', 'description', 'tags')),
              ('Route Targets', ('import_targets', 'export_targets')),
              ('Tenancy', ('tenant_group', 'tenant')),
          )
          labels = {
              'rd': "RD",
          }
          help_texts = {
              'rd': "Route distinguisher in any format",
          }
  
  
  class RouteTargetForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
      tags = DynamicModelMultipleChoiceField(
          queryset=Tag.objects.all(),
          required=False
      )
  
      class Meta:
          model = RouteTarget
          fields = [
              'name', 'description', 'tenant_group', 'tenant', 'tags',
          ]
          fieldsets = (
              ('Route Target', ('name', 'description', 'tags')),
              ('Tenancy', ('tenant_group', 'tenant')),
          )
  
  
  class RIRForm(BootstrapMixin, CustomFieldModelForm):
      slug = SlugField()
  
      class Meta:
          model = RIR
          fields = [
              'name', 'slug', 'is_private', 'description',
          ]
  
  
  class AggregateForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
      rir = DynamicModelChoiceField(
          queryset=RIR.objects.all(),
          label='RIR'
      )
      tags = DynamicModelMultipleChoiceField(
          queryset=Tag.objects.all(),
          required=False
      )
  
      class Meta:
          model = Aggregate
          fields = [
              'prefix', 'rir', 'date_added', 'description', 'tenant_group', 'tenant', 'tags',
          ]
          fieldsets = (
              ('Aggregate', ('prefix', 'rir', 'date_added', 'description', 'tags')),
              ('Tenancy', ('tenant_group', 'tenant')),
          )
          help_texts = {
              'prefix': "IPv4 or IPv6 network",
              'rir': "Regional Internet Registry responsible for this prefix",
          }
          widgets = {
              'date_added': DatePicker(),
          }
  
  
  class RoleForm(BootstrapMixin, CustomFieldModelForm):
      slug = SlugField()
  
      class Meta:
          model = Role
          fields = [
              'name', 'slug', 'weight', 'description',
          ]
  
  
  class PrefixForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
      vrf = DynamicModelChoiceField(
          queryset=VRF.objects.all(),
          required=False,
          label='VRF'
      )
      region = DynamicModelChoiceField(
          queryset=Region.objects.all(),
          required=False,
          initial_params={
              'sites': '$site'
          }
      )
      site_group = DynamicModelChoiceField(
          queryset=SiteGroup.objects.all(),
          required=False,
          initial_params={
              'sites': '$site'
          }
      )
      site = DynamicModelChoiceField(
          queryset=Site.objects.all(),
          required=False,
          null_option='None',
          query_params={
              'region_id': '$region',
              'group_id': '$site_group',
          }
      )
      vlan_group = DynamicModelChoiceField(
          queryset=VLANGroup.objects.all(),
          required=False,
          label='VLAN group',
          null_option='None',
          query_params={
              'site_id': '$site'
          },
          initial_params={
              'vlans': '$vlan'
          }
      )
      vlan = DynamicModelChoiceField(
          queryset=VLAN.objects.all(),
          required=False,
          label='VLAN',
          query_params={
              'site_id': '$site',
              'group_id': '$vlan_group',
          }
      )
      role = DynamicModelChoiceField(
          queryset=Role.objects.all(),
          required=False
      )
      tags = DynamicModelMultipleChoiceField(
          queryset=Tag.objects.all(),
          required=False
      )
  
      class Meta:
          model = Prefix
          fields = [
              'prefix', 'vrf', 'site', 'vlan', 'status', 'role', 'is_pool', 'mark_utilized', 'description',
              'tenant_group', 'tenant', 'tags',
          ]
          fieldsets = (
              ('Prefix', ('prefix', 'status', 'vrf', 'role', 'is_pool', 'mark_utilized', 'description', 'tags')),
              ('Site/VLAN Assignment', ('region', 'site_group', 'site', 'vlan_group', 'vlan')),
              ('Tenancy', ('tenant_group', 'tenant')),
          )
          widgets = {
              'status': StaticSelect(),
          }
  
  
  class IPRangeForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
      vrf = DynamicModelChoiceField(
          queryset=VRF.objects.all(),
          required=False,
          label='VRF'
      )
      role = DynamicModelChoiceField(
          queryset=Role.objects.all(),
          required=False
      )
      tags = DynamicModelMultipleChoiceField(
          queryset=Tag.objects.all(),
          required=False
      )
  
      class Meta:
          model = IPRange
          fields = [
              'vrf', 'start_address', 'end_address', 'status', 'role', 'description', 'tenant_group', 'tenant', 'tags',
          ]
          fieldsets = (
              ('IP Range', ('vrf', 'start_address', 'end_address', 'role', 'status', 'description', 'tags')),
              ('Tenancy', ('tenant_group', 'tenant')),
          )
          widgets = {
              'status': StaticSelect(),
          }
  
  
  class IPAddressForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
      device = DynamicModelChoiceField(
          queryset=Device.objects.all(),
          required=False,
          initial_params={
              'interfaces': '$interface'
          }
      )
      interface = DynamicModelChoiceField(
          queryset=Interface.objects.all(),
          required=False,
          query_params={
              'device_id': '$device'
          }
      )
      virtual_machine = DynamicModelChoiceField(
          queryset=VirtualMachine.objects.all(),
          required=False,
          initial_params={
              'interfaces': '$vminterface'
          }
      )
      vminterface = DynamicModelChoiceField(
          queryset=VMInterface.objects.all(),
          required=False,
          label='Interface',
          query_params={
              'virtual_machine_id': '$virtual_machine'
          }
      )
      vrf = DynamicModelChoiceField(
          queryset=VRF.objects.all(),
          required=False,
          label='VRF'
      )
      nat_region = DynamicModelChoiceField(
          queryset=Region.objects.all(),
          required=False,
          label='Region',
          initial_params={
              'sites': '$nat_site'
          }
      )
      nat_site_group = DynamicModelChoiceField(
          queryset=SiteGroup.objects.all(),
          required=False,
          label='Site group',
          initial_params={
              'sites': '$nat_site'
          }
      )
      nat_site = DynamicModelChoiceField(
          queryset=Site.objects.all(),
          required=False,
          label='Site',
          query_params={
              'region_id': '$nat_region',
              'group_id': '$nat_site_group',
          }
      )
      nat_rack = DynamicModelChoiceField(
          queryset=Rack.objects.all(),
          required=False,
          label='Rack',
          null_option='None',
          query_params={
              'site_id': '$site'
          }
      )
      nat_device = DynamicModelChoiceField(
          queryset=Device.objects.all(),
          required=False,
          label='Device',
          query_params={
              'site_id': '$site',
              'rack_id': '$nat_rack',
          }
      )
      nat_cluster = DynamicModelChoiceField(
          queryset=Cluster.objects.all(),
          required=False,
          label='Cluster'
      )
      nat_virtual_machine = DynamicModelChoiceField(
          queryset=VirtualMachine.objects.all(),
          required=False,
          label='Virtual Machine',
          query_params={
              'cluster_id': '$nat_cluster',
          }
      )
      nat_vrf = DynamicModelChoiceField(
          queryset=VRF.objects.all(),
          required=False,
          label='VRF'
      )
      nat_inside = DynamicModelChoiceField(
          queryset=IPAddress.objects.all(),
          required=False,
          label='IP Address',
          query_params={
              'device_id': '$nat_device',
              'virtual_machine_id': '$nat_virtual_machine',
              'vrf_id': '$nat_vrf',
          }
      )
      primary_for_parent = forms.BooleanField(
          required=False,
          label='Make this the primary IP for the device/VM'
      )
      tags = DynamicModelMultipleChoiceField(
          queryset=Tag.objects.all(),
          required=False
      )
  
      class Meta:
          model = IPAddress
          fields = [
              'address', 'vrf', 'status', 'role', 'dns_name', 'description', 'primary_for_parent', 'nat_site', 'nat_rack',
              'nat_device', 'nat_cluster', 'nat_virtual_machine', 'nat_vrf', 'nat_inside', 'tenant_group', 'tenant',
              'tags',
          ]
          widgets = {
              'status': StaticSelect(),
              'role': StaticSelect(),
          }
  
      def __init__(self, *args, **kwargs):
  
          # Initialize helper selectors
          instance = kwargs.get('instance')
          initial = kwargs.get('initial', {}).copy()
          if instance:
              if type(instance.assigned_object) is Interface:
                  initial['interface'] = instance.assigned_object
              elif type(instance.assigned_object) is VMInterface:
                  initial['vminterface'] = instance.assigned_object
              if instance.nat_inside:
                  nat_inside_parent = instance.nat_inside.assigned_object
                  if type(nat_inside_parent) is Interface:
                      initial['nat_site'] = nat_inside_parent.device.site.pk
                      if nat_inside_parent.device.rack:
                          initial['nat_rack'] = nat_inside_parent.device.rack.pk
                      initial['nat_device'] = nat_inside_parent.device.pk
                  elif type(nat_inside_parent) is VMInterface:
                      initial['nat_cluster'] = nat_inside_parent.virtual_machine.cluster.pk
                      initial['nat_virtual_machine'] = nat_inside_parent.virtual_machine.pk
          kwargs['initial'] = initial
  
          super().__init__(*args, **kwargs)
  
          # Initialize primary_for_parent if IP address is already assigned
          if self.instance.pk and self.instance.assigned_object:
              parent = self.instance.assigned_object.parent_object
              if (
                  self.instance.address.version == 4 and parent.primary_ip4_id == self.instance.pk or
                  self.instance.address.version == 6 and parent.primary_ip6_id == self.instance.pk
              ):
                  self.initial['primary_for_parent'] = True
  
      def clean(self):
          super().clean()
  
          # Cannot select both a device interface and a VM interface
          if self.cleaned_data.get('interface') and self.cleaned_data.get('vminterface'):
              raise forms.ValidationError("Cannot select both a device interface and a virtual machine interface")
          self.instance.assigned_object = self.cleaned_data.get('interface') or self.cleaned_data.get('vminterface')
  
          # Primary IP assignment is only available if an interface has been assigned.
          interface = self.cleaned_data.get('interface') or self.cleaned_data.get('vminterface')
          if self.cleaned_data.get('primary_for_parent') and not interface:
              self.add_error(
                  'primary_for_parent', "Only IP addresses assigned to an interface can be designated as primary IPs."
              )
  
      def save(self, *args, **kwargs):
          ipaddress = super().save(*args, **kwargs)
  
          # Assign/clear this IPAddress as the primary for the associated Device/VirtualMachine.
          interface = self.instance.assigned_object
          if interface:
              parent = interface.parent_object
              if self.cleaned_data['primary_for_parent']:
                  if ipaddress.address.version == 4:
                      parent.primary_ip4 = ipaddress
                  else:
                      parent.primary_ip6 = ipaddress
                  parent.save()
              elif ipaddress.address.version == 4 and parent.primary_ip4 == ipaddress:
                  parent.primary_ip4 = None
                  parent.save()
              elif ipaddress.address.version == 6 and parent.primary_ip6 == ipaddress:
                  parent.primary_ip6 = None
                  parent.save()
  
          return ipaddress
  
  
  class IPAddressBulkAddForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
      vrf = DynamicModelChoiceField(
          queryset=VRF.objects.all(),
          required=False,
          label='VRF'
      )
      tags = DynamicModelMultipleChoiceField(
          queryset=Tag.objects.all(),
          required=False
      )
  
      class Meta:
          model = IPAddress
          fields = [
              'address', 'vrf', 'status', 'role', 'dns_name', 'description', 'tenant_group', 'tenant', 'tags',
          ]
          widgets = {
              'status': StaticSelect(),
              'role': StaticSelect(),
          }
  
  
  class IPAddressAssignForm(BootstrapMixin, forms.Form):
      vrf_id = DynamicModelChoiceField(
          queryset=VRF.objects.all(),
          required=False,
          label='VRF'
      )
      q = forms.CharField(
          required=False,
          label='Search',
      )
  
  
  class VLANGroupForm(BootstrapMixin, CustomFieldModelForm):
      scope_type = ContentTypeChoiceField(
          queryset=ContentType.objects.filter(model__in=VLANGROUP_SCOPE_TYPES),
          required=False,
          widget=StaticSelect
      )
      region = DynamicModelChoiceField(
          queryset=Region.objects.all(),
          required=False,
          initial_params={
              'sites': '$site'
          }
      )
      sitegroup = DynamicModelChoiceField(
          queryset=SiteGroup.objects.all(),
          required=False,
          initial_params={
              'sites': '$site'
          },
          label='Site group'
      )
      site = DynamicModelChoiceField(
          queryset=Site.objects.all(),
          required=False,
          initial_params={
              'locations': '$location'
          },
          query_params={
              'region_id': '$region',
              'group_id': '$sitegroup',
          }
      )
      location = DynamicModelChoiceField(
          queryset=Location.objects.all(),
          required=False,
          initial_params={
              'racks': '$rack'
          },
          query_params={
              'site_id': '$site',
          }
      )
      rack = DynamicModelChoiceField(
          queryset=Rack.objects.all(),
          required=False,
          query_params={
              'site_id': '$site',
              'location_id': '$location',
          }
      )
      clustergroup = DynamicModelChoiceField(
          queryset=ClusterGroup.objects.all(),
          required=False,
          initial_params={
              'clusters': '$cluster'
          },
          label='Cluster group'
      )
      cluster = DynamicModelChoiceField(
          queryset=Cluster.objects.all(),
          required=False,
          query_params={
              'group_id': '$clustergroup',
          }
      )
      slug = SlugField()
  
      class Meta:
          model = VLANGroup
          fields = [
              'name', 'slug', 'description', 'scope_type', 'region', 'sitegroup', 'site', 'location', 'rack',
              'clustergroup', 'cluster',
          ]
          fieldsets = (
              ('VLAN Group', ('name', 'slug', 'description')),
              ('Scope', ('scope_type', 'region', 'sitegroup', 'site', 'location', 'rack', 'clustergroup', 'cluster')),
          )
          widgets = {
              'scope_type': StaticSelect,
          }
  
      def __init__(self, *args, **kwargs):
          instance = kwargs.get('instance')
          initial = kwargs.get('initial', {})
  
          if instance is not None and instance.scope:
              initial[instance.scope_type.model] = instance.scope
  
              kwargs['initial'] = initial
  
          super().__init__(*args, **kwargs)
  
      def clean(self):
          super().clean()
  
          # Assign scope based on scope_type
          if self.cleaned_data.get('scope_type'):
              scope_field = self.cleaned_data['scope_type'].model
              self.instance.scope = self.cleaned_data.get(scope_field)
          else:
              self.instance.scope_id = None
  
  
  class VLANForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
      # VLANGroup assignment fields
      scope_type = forms.ChoiceField(
          choices=(
              ('', ''),
              ('dcim.region', 'Region'),
              ('dcim.sitegroup', 'Site group'),
              ('dcim.site', 'Site'),
              ('dcim.location', 'Location'),
              ('dcim.rack', 'Rack'),
              ('virtualization.clustergroup', 'Cluster group'),
              ('virtualization.cluster', 'Cluster'),
          ),
          required=False,
          widget=StaticSelect,
          label='Group scope'
      )
      group = DynamicModelChoiceField(
          queryset=VLANGroup.objects.all(),
          required=False,
          query_params={
              'scope_type': '$scope_type',
          },
          label='VLAN Group'
      )
  
      # Site assignment fields
      region = DynamicModelChoiceField(
          queryset=Region.objects.all(),
          required=False,
          initial_params={
              'sites': '$site'
          },
          label='Region'
      )
      sitegroup = DynamicModelChoiceField(
          queryset=SiteGroup.objects.all(),
          required=False,
          initial_params={
              'sites': '$site'
          },
          label='Site group'
      )
      site = DynamicModelChoiceField(
          queryset=Site.objects.all(),
          required=False,
          null_option='None',
          query_params={
              'region_id': '$region',
              'group_id': '$sitegroup',
          }
      )
  
      # Other fields
      role = DynamicModelChoiceField(
          queryset=Role.objects.all(),
          required=False
      )
      tags = DynamicModelMultipleChoiceField(
          queryset=Tag.objects.all(),
          required=False
      )
  
      class Meta:
          model = VLAN
          fields = [
              'site', 'group', 'vid', 'name', 'status', 'role', 'description', 'tenant_group', 'tenant', 'tags',
          ]
          help_texts = {
              'site': "Leave blank if this VLAN spans multiple sites",
              'group': "VLAN group (optional)",
              'vid': "Configured VLAN ID",
              'name': "Configured VLAN name",
              'status': "Operational status of this VLAN",
              'role': "The primary function of this VLAN",
          }
          widgets = {
              'status': StaticSelect(),
          }
  
  
  class ServiceForm(BootstrapMixin, CustomFieldModelForm):
      ports = NumericArrayField(
          base_field=forms.IntegerField(
              min_value=SERVICE_PORT_MIN,
              max_value=SERVICE_PORT_MAX
          ),
          help_text="Comma-separated list of one or more port numbers. A range may be specified using a hyphen."
      )
      tags = DynamicModelMultipleChoiceField(
          queryset=Tag.objects.all(),
          required=False
      )
  
      class Meta:
          model = Service
          fields = [
              'name', 'protocol', 'ports', 'ipaddresses', 'description', 'tags',
          ]
          help_texts = {
              'ipaddresses': "IP address assignment is optional. If no IPs are selected, the service is assumed to be "
                             "reachable via all IPs assigned to the device.",
          }
          widgets = {
              'protocol': StaticSelect(),
              'ipaddresses': StaticSelectMultiple(),
          }
  
      def __init__(self, *args, **kwargs):
          super().__init__(*args, **kwargs)
  
          # Limit IP address choices to those assigned to interfaces of the parent device/VM
          if self.instance.device:
              self.fields['ipaddresses'].queryset = IPAddress.objects.filter(
                  interface__in=self.instance.device.vc_interfaces().values_list('id', flat=True)
              )
          elif self.instance.virtual_machine:
              self.fields['ipaddresses'].queryset = IPAddress.objects.filter(
                  vminterface__in=self.instance.virtual_machine.interfaces.values_list('id', flat=True)
              )
          else:
              self.fields['ipaddresses'].choices = []
  