class CustomLinkBulkEditForm(BulkEditForm): pk = forms.ModelMultipleChoiceField( queryset=CustomLink.objects.all(), widget=forms.MultipleHiddenInput ) content_type = ContentTypeChoiceField( queryset=ContentType.objects.all(), limit_choices_to=FeatureQuery('custom_links'), required=False ) new_window = forms.NullBooleanField( required=False, widget=BulkEditNullBooleanSelect() ) weight = forms.IntegerField( required=False ) button_class = forms.ChoiceField( choices=add_blank_choice(CustomLinkButtonClassChoices), required=False, widget=StaticSelect() ) class Meta: nullable_fields = []
class VRFBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm): pk = forms.ModelMultipleChoiceField( queryset=VRF.objects.all(), widget=forms.MultipleHiddenInput() ) tenant = forms.ModelChoiceField( queryset=Tenant.objects.all(), required=False, widget=APISelect( api_url="/api/tenancy/tenants/" ) ) enforce_unique = forms.NullBooleanField( required=False, widget=BulkEditNullBooleanSelect(), label='Enforce unique space' ) description = forms.CharField( max_length=100, required=False ) class Meta: nullable_fields = [ 'tenant', 'description', ]
class VRFBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm): pk = forms.ModelMultipleChoiceField( queryset=VRF.objects.all(), widget=forms.MultipleHiddenInput() ) tenant = DynamicModelChoiceField( label='Учреждение', queryset=Tenant.objects.all(), required=False ) enforce_unique = forms.NullBooleanField( required=False, widget=BulkEditNullBooleanSelect(), label='Принудительное использование уникального пространства' ) description = forms.CharField( label='Описание', max_length=100, required=False ) class Meta: nullable_fields = [ 'tenant', 'description', ]
class ExportTemplateBulkEditForm(BulkEditForm): pk = forms.ModelMultipleChoiceField( queryset=ExportTemplate.objects.all(), widget=forms.MultipleHiddenInput ) content_type = ContentTypeChoiceField( queryset=ContentType.objects.all(), limit_choices_to=FeatureQuery('export_templates'), required=False ) description = forms.CharField( max_length=200, required=False ) mime_type = forms.CharField( max_length=50, required=False ) file_extension = forms.CharField( max_length=15, required=False ) as_attachment = forms.NullBooleanField( required=False, widget=BulkEditNullBooleanSelect() ) class Meta: nullable_fields = ['description', 'mime_type', 'file_extension']
class PrefixBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm): pk = forms.ModelMultipleChoiceField(queryset=Prefix.objects.all(), widget=forms.MultipleHiddenInput()) site = forms.ModelChoiceField(queryset=Site.objects.all(), required=False) vrf = forms.ModelChoiceField(queryset=VRF.objects.all(), required=False, label='VRF') tenant = forms.ModelChoiceField(queryset=Tenant.objects.all(), required=False) status = forms.ChoiceField(choices=add_blank_choice(PREFIX_STATUS_CHOICES), required=False) role = forms.ModelChoiceField(queryset=Role.objects.all(), required=False) is_pool = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect(), label='Is a pool') description = forms.CharField(max_length=100, required=False) class Meta: nullable_fields = [ 'site', 'vrf', 'tenant', 'role', 'description', ]
class PrefixBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm): pk = forms.ModelMultipleChoiceField(queryset=Prefix.objects.all(), widget=forms.MultipleHiddenInput()) site = DynamicModelChoiceField(queryset=Site.objects.all(), required=False) vrf = DynamicModelChoiceField(queryset=VRF.objects.all(), required=False, label='VRF') prefix_length = forms.IntegerField(min_value=PREFIX_LENGTH_MIN, max_value=PREFIX_LENGTH_MAX, required=False) tenant = DynamicModelChoiceField(queryset=Tenant.objects.all(), required=False) status = forms.ChoiceField(choices=add_blank_choice(PrefixStatusChoices), required=False, widget=StaticSelect2()) role = DynamicModelChoiceField(queryset=Role.objects.all(), required=False) is_pool = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect(), label='Is a pool') description = forms.CharField(max_length=100, required=False) class Meta: nullable_fields = [ 'site', 'vrf', 'tenant', 'role', 'description', ]
class PrefixBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm): pk = forms.ModelMultipleChoiceField( queryset=Prefix.objects.all(), widget=forms.MultipleHiddenInput() ) site = forms.ModelChoiceField( queryset=Site.objects.all(), required=False, widget=APISelect( api_url="/api/dcim/sites/" ) ) vrf = forms.ModelChoiceField( queryset=VRF.objects.all(), required=False, label='VRF', widget=APISelect( api_url="/api/ipam/vrfs/" ) ) prefix_length = forms.IntegerField( min_value=1, max_value=127, required=False ) tenant = forms.ModelChoiceField( queryset=Tenant.objects.all(), required=False, widget=APISelect( api_url="/api/tenancy/tenants/" ) ) status = forms.ChoiceField( choices=add_blank_choice(PREFIX_STATUS_CHOICES), required=False, widget=StaticSelect2() ) role = forms.ModelChoiceField( queryset=Role.objects.all(), required=False, widget=APISelect( api_url="/api/ipam/roles/" ) ) is_pool = forms.NullBooleanField( required=False, widget=BulkEditNullBooleanSelect(), label='Is a pool' ) description = forms.CharField( max_length=100, required=False ) class Meta: nullable_fields = [ 'site', 'vrf', 'tenant', 'role', 'description', ]
class InterfaceBulkEditForm(BootstrapMixin, BulkEditForm): pk = forms.ModelMultipleChoiceField(queryset=Interface.objects.all(), widget=forms.MultipleHiddenInput()) virtual_machine = forms.ModelChoiceField( queryset=VirtualMachine.objects.all(), widget=forms.HiddenInput()) enabled = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect()) mtu = forms.IntegerField(required=False, min_value=INTERFACE_MTU_MIN, max_value=INTERFACE_MTU_MAX, label='MTU') description = forms.CharField(max_length=100, required=False) mode = forms.ChoiceField(choices=add_blank_choice(InterfaceModeChoices), required=False, widget=StaticSelect2()) untagged_vlan = DynamicModelChoiceField(queryset=VLAN.objects.all(), required=False, widget=APISelect( api_url="/api/ipam/vlans/", display_field='display_name', full=True, additional_query_params={ 'site_id': 'null', }, )) tagged_vlans = DynamicModelMultipleChoiceField( queryset=VLAN.objects.all(), required=False, widget=APISelectMultiple( api_url="/api/ipam/vlans/", display_field='display_name', full=True, additional_query_params={ 'site_id': 'null', }, )) class Meta: nullable_fields = [ 'mtu', 'description', ] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Limit available VLANs based on the parent VirtualMachine if 'virtual_machine' in self.initial: parent_obj = VirtualMachine.objects.filter( pk=self.initial['virtual_machine']).first() site = getattr(parent_obj.cluster, 'site', None) if site is not None: # Add current site to VLANs query params self.fields['untagged_vlan'].widget.add_additional_query_param( 'site_id', site.pk) self.fields['tagged_vlans'].widget.add_additional_query_param( 'site_id', site.pk)
class WebhookBulkEditForm(BulkEditForm): pk = forms.ModelMultipleChoiceField( queryset=Webhook.objects.all(), widget=forms.MultipleHiddenInput ) enabled = forms.NullBooleanField( required=False, widget=BulkEditNullBooleanSelect() ) type_create = forms.NullBooleanField( required=False, widget=BulkEditNullBooleanSelect() ) type_update = forms.NullBooleanField( required=False, widget=BulkEditNullBooleanSelect() ) type_delete = forms.NullBooleanField( required=False, widget=BulkEditNullBooleanSelect() ) http_method = forms.ChoiceField( choices=add_blank_choice(WebhookHttpMethodChoices), required=False, label='HTTP method' ) payload_url = forms.CharField( required=False, label='Payload URL' ) ssl_verification = forms.NullBooleanField( required=False, widget=BulkEditNullBooleanSelect(), label='SSL verification' ) secret = forms.CharField( required=False ) ca_file_path = forms.CharField( required=False, label='CA file path' ) class Meta: nullable_fields = ['secret', 'conditions', 'ca_file_path']
class CustomFieldBulkEditForm(BulkEditForm): pk = forms.ModelMultipleChoiceField(queryset=CustomField.objects.all(), widget=forms.MultipleHiddenInput) description = forms.CharField(required=False) required = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect()) weight = forms.IntegerField(required=False) class Meta: nullable_fields = []
class PrefixBulkEditForm(AddRemoveTagsForm, CustomFieldModelBulkEditForm): pk = forms.ModelMultipleChoiceField(queryset=Prefix.objects.all(), widget=forms.MultipleHiddenInput()) region = DynamicModelChoiceField(queryset=Region.objects.all(), required=False) site_group = DynamicModelChoiceField(queryset=SiteGroup.objects.all(), required=False) site = DynamicModelChoiceField(queryset=Site.objects.all(), required=False, query_params={ 'region_id': '$region', 'group_id': '$site_group', }) vrf = DynamicModelChoiceField(queryset=VRF.objects.all(), required=False, label='VRF') prefix_length = forms.IntegerField(min_value=PREFIX_LENGTH_MIN, max_value=PREFIX_LENGTH_MAX, required=False) tenant = DynamicModelChoiceField(queryset=Tenant.objects.all(), required=False) status = forms.ChoiceField(choices=add_blank_choice(PrefixStatusChoices), required=False, widget=StaticSelect()) role = DynamicModelChoiceField(queryset=Role.objects.all(), required=False) is_pool = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect(), label='Is a pool') mark_utilized = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect(), label='Treat as 100% utilized') description = forms.CharField(max_length=100, required=False) class Meta: nullable_fields = [ 'site', 'vrf', 'tenant', 'role', 'description', ]
class WebhookBulkEditForm(BootstrapMixin, BulkEditForm): pk = forms.ModelMultipleChoiceField(queryset=Webhook.objects.all(), widget=forms.MultipleHiddenInput) enabled = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect()) type_create = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect()) type_update = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect()) type_delete = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect()) http_method = forms.ChoiceField(choices=WebhookHttpMethodChoices, required=False) payload_url = forms.CharField(required=False) ssl_verification = forms.NullBooleanField( required=False, widget=BulkEditNullBooleanSelect()) secret = forms.CharField(required=False) ca_file_path = forms.CharField(required=False) class Meta: nullable_fields = ['secret', 'ca_file_path']
class ConfigContextBulkEditForm(BootstrapMixin, BulkEditForm): pk = forms.ModelMultipleChoiceField(queryset=ConfigContext.objects.all(), widget=forms.MultipleHiddenInput) weight = forms.IntegerField(required=False, min_value=0) is_active = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect()) description = forms.CharField(required=False, max_length=100) class Meta: nullable_fields = [ 'description', ]
class DeviceTypeBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm): pk = forms.ModelMultipleChoiceField(queryset=DeviceType.objects.all(), widget=forms.MultipleHiddenInput()) manufacturer = DynamicModelChoiceField(queryset=Manufacturer.objects.all(), required=False) u_height = forms.IntegerField(min_value=1, required=False) is_full_depth = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect(), label='Is full depth') class Meta: nullable_fields = []
class DeviceTypeBulkEditForm(AddRemoveTagsForm, CustomFieldModelBulkEditForm): pk = forms.ModelMultipleChoiceField(queryset=DeviceType.objects.all(), widget=forms.MultipleHiddenInput()) manufacturer = DynamicModelChoiceField(queryset=Manufacturer.objects.all(), required=False) u_height = forms.IntegerField(min_value=1, required=False) is_full_depth = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect(), label='Is full depth') airflow = forms.ChoiceField(choices=add_blank_choice(DeviceAirflowChoices), required=False, widget=StaticSelect()) class Meta: nullable_fields = ['airflow']
class InterfaceBulkEditForm(BootstrapMixin, BulkEditForm): pk = forms.ModelMultipleChoiceField(queryset=Interface.objects.all(), widget=forms.MultipleHiddenInput()) enabled = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect()) mtu = forms.IntegerField(required=False, min_value=1, max_value=32767, label='MTU') description = forms.CharField(max_length=100, required=False) class Meta: nullable_fields = [ 'mtu', 'description', ]
class VMInterfaceBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEditForm): pk = forms.ModelMultipleChoiceField(queryset=VMInterface.objects.all(), widget=forms.MultipleHiddenInput()) virtual_machine = forms.ModelChoiceField( queryset=VirtualMachine.objects.all(), required=False, disabled=True, widget=forms.HiddenInput()) parent = DynamicModelChoiceField(queryset=VMInterface.objects.all(), required=False) enabled = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect()) mtu = forms.IntegerField(required=False, min_value=INTERFACE_MTU_MIN, max_value=INTERFACE_MTU_MAX, label='MTU') description = forms.CharField(max_length=100, required=False) mode = forms.ChoiceField(choices=add_blank_choice(InterfaceModeChoices), required=False, widget=StaticSelect()) untagged_vlan = DynamicModelChoiceField(queryset=VLAN.objects.all(), required=False) tagged_vlans = DynamicModelMultipleChoiceField(queryset=VLAN.objects.all(), required=False) class Meta: nullable_fields = [ 'parent', 'mtu', 'description', ] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if 'virtual_machine' in self.initial: vm_id = self.initial.get('virtual_machine') # Restrict parent interface assignment by VM self.fields['parent'].widget.add_query_param( 'virtual_machine_id', vm_id) # Limit VLAN choices by virtual machine self.fields['untagged_vlan'].widget.add_query_param( 'available_on_virtualmachine', vm_id) self.fields['tagged_vlans'].widget.add_query_param( 'available_on_virtualmachine', vm_id) else: # See 5643 if 'pk' in self.initial: site = None interfaces = VMInterface.objects.filter( pk__in=self.initial['pk']).prefetch_related( 'virtual_machine__cluster__site') # Check interface sites. First interface should set site, further interfaces will either continue the # loop or reset back to no site and break the loop. for interface in interfaces: if site is None: site = interface.virtual_machine.cluster.site elif interface.virtual_machine.cluster.site is not site: site = None break if site is not None: self.fields['untagged_vlan'].widget.add_query_param( 'site_id', site.pk) self.fields['tagged_vlans'].widget.add_query_param( 'site_id', site.pk)
class PrefixBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm): pk = forms.ModelMultipleChoiceField( queryset=Prefix.objects.all(), widget=forms.MultipleHiddenInput() ) region = DynamicModelChoiceField( label='Регион', queryset=Region.objects.all(), required=False ) site_group = DynamicModelChoiceField( label='site_group', queryset=SiteGroup.objects.all(), required=False ) site = DynamicModelChoiceField( label='Адрес', queryset=Site.objects.all(), required=False, query_params={ 'region_id': '$region', 'group_id': '$site_group', } ) vrf = DynamicModelChoiceField( queryset=VRF.objects.all(), required=False, label='VRF' ) prefix_length = forms.IntegerField( label='prefix_length', min_value=PREFIX_LENGTH_MIN, max_value=PREFIX_LENGTH_MAX, required=False ) tenant = DynamicModelChoiceField( label='Учреждение', queryset=Tenant.objects.all(), required=False ) status = forms.ChoiceField( label='Статус', choices=add_blank_choice(PrefixStatusChoices), required=False, widget=StaticSelect2() ) role = DynamicModelChoiceField( label='Роль', queryset=Role.objects.all(), required=False ) is_pool = forms.NullBooleanField( required=False, widget=BulkEditNullBooleanSelect(), label='Это диапазон адресов' ) description = forms.CharField( label='Описание', max_length=100, required=False ) class Meta: nullable_fields = [ 'site', 'vrf', 'tenant', 'role', 'description', ]
class InterfaceBulkEditForm(BootstrapMixin, BulkEditForm): pk = forms.ModelMultipleChoiceField( queryset=Interface.objects.all(), widget=forms.MultipleHiddenInput() ) enabled = forms.NullBooleanField( required=False, widget=BulkEditNullBooleanSelect() ) mtu = forms.IntegerField( required=False, min_value=INTERFACE_MTU_MIN, max_value=INTERFACE_MTU_MAX, label='MTU' ) description = forms.CharField( max_length=100, required=False ) mode = forms.ChoiceField( choices=add_blank_choice(InterfaceModeChoices), required=False, widget=StaticSelect2() ) untagged_vlan = forms.ModelChoiceField( queryset=VLAN.objects.all(), required=False, widget=APISelect( api_url="/api/ipam/vlans/", display_field='display_name', full=True ) ) tagged_vlans = forms.ModelMultipleChoiceField( queryset=VLAN.objects.all(), required=False, widget=APISelectMultiple( api_url="/api/ipam/vlans/", display_field='display_name', full=True ) ) class Meta: nullable_fields = [ 'mtu', 'description', ] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Limit VLan choices to those in: global vlans, global groups, the current site's group, the current site vlan_choices = [] global_vlans = VLAN.objects.filter(site=None, group=None) vlan_choices.append( ('Global', [(vlan.pk, vlan) for vlan in global_vlans]) ) for group in VLANGroup.objects.filter(site=None): global_group_vlans = VLAN.objects.filter(group=group) vlan_choices.append( (group.name, [(vlan.pk, vlan) for vlan in global_group_vlans]) ) if self.parent_obj.cluster is not None: site = getattr(self.parent_obj.cluster, 'site', None) if site is not None: # Add non-grouped site VLANs site_vlans = VLAN.objects.filter(site=site, group=None) vlan_choices.append((site.name, [(vlan.pk, vlan) for vlan in site_vlans])) # Add grouped site VLANs for group in VLANGroup.objects.filter(site=site): site_group_vlans = VLAN.objects.filter(group=group) vlan_choices.append(( '{} / {}'.format(group.site.name, group.name), [(vlan.pk, vlan) for vlan in site_group_vlans] )) self.fields['untagged_vlan'].choices = [(None, '---------')] + vlan_choices self.fields['tagged_vlans'].choices = vlan_choices