class IPAddressForm(BootstrapMixin, CustomFieldForm): nat_site = forms.ModelChoiceField(queryset=Site.objects.all(), required=False, label='Site', widget=forms.Select(attrs={'filter-for': 'nat_device'})) nat_device = forms.ModelChoiceField(queryset=Device.objects.all(), required=False, label='Device', widget=APISelect(api_url='/api/dcim/devices/?site_id={{nat_site}}', display_field='display_name', attrs={'filter-for': 'nat_inside'})) livesearch = forms.CharField(required=False, label='IP Address', widget=Livesearch( query_key='q', query_url='ipam-api:ipaddress_list', field_to_update='nat_inside', obj_label='address') ) nat_inside = forms.ModelChoiceField(queryset=IPAddress.objects.all(), required=False, label='NAT (Inside)', widget=APISelect(api_url='/api/ipam/ip-addresses/?device_id={{nat_device}}', display_field='address')) class Meta: model = IPAddress fields = ['address', 'vrf', 'tenant', 'nat_device', 'nat_inside', 'description'] help_texts = { 'address': "IPv4 or IPv6 address and mask", 'vrf': "VRF (if applicable)", } def __init__(self, *args, **kwargs): super(IPAddressForm, self).__init__(*args, **kwargs) self.fields['vrf'].empty_label = 'Global' if self.instance.nat_inside: nat_inside = self.instance.nat_inside # If the IP is assigned to an interface, populate site/device fields accordingly if self.instance.nat_inside.interface: self.initial['nat_site'] = self.instance.nat_inside.interface.device.rack.site.pk self.initial['nat_device'] = self.instance.nat_inside.interface.device.pk self.fields['nat_device'].queryset = Device.objects.filter( rack__site=nat_inside.interface.device.rack.site) self.fields['nat_inside'].queryset = IPAddress.objects.filter( interface__device=nat_inside.interface.device) else: self.fields['nat_inside'].queryset = IPAddress.objects.filter(pk=nat_inside.pk) else: # Initialize nat_device choices if nat_site is set if self.is_bound and self.data.get('nat_site'): self.fields['nat_device'].queryset = Device.objects.filter(rack__site__pk=self.data['nat_site']) elif self.initial.get('nat_site'): self.fields['nat_device'].queryset = Device.objects.filter(rack__site=self.initial['nat_site']) else: self.fields['nat_device'].choices = [] # Initialize nat_inside choices if nat_device is set if self.is_bound and self.data.get('nat_device'): self.fields['nat_inside'].queryset = IPAddress.objects.filter( interface__device__pk=self.data['nat_device']) elif self.initial.get('nat_device'): self.fields['nat_inside'].queryset = IPAddress.objects.filter( interface__device__pk=self.initial['nat_device']) else: self.fields['nat_inside'].choices = []
class IPAddressAssignForm(BootstrapMixin, forms.Form): site = forms.ModelChoiceField( queryset=Site.objects.all(), label='Site', required=False, widget=forms.Select( attrs={'filter-for': 'rack'} ) ) rack = forms.ModelChoiceField( queryset=Rack.objects.all(), label='Rack', required=False, widget=APISelect( api_url='/api/dcim/racks/?site_id={{site}}', display_field='display_name', attrs={'filter-for': 'device', 'nullable': 'true'} ) ) device = forms.ModelChoiceField( queryset=Device.objects.all(), label='Device', required=False, widget=APISelect( api_url='/api/dcim/devices/?site_id={{site}}&rack_id={{rack}}', display_field='display_name', attrs={'filter-for': 'interface'} ) ) livesearch = forms.CharField( required=False, label='Device', widget=Livesearch( query_key='q', query_url='dcim-api:device_list', field_to_update='device' ) ) interface = forms.ModelChoiceField( queryset=Interface.objects.all(), label='Interface', widget=APISelect( api_url='/api/dcim/devices/{{device}}/interfaces/' ) ) set_as_primary = forms.BooleanField( label='Set as primary IP for device', required=False ) def __init__(self, *args, **kwargs): super(IPAddressAssignForm, self).__init__(*args, **kwargs) self.fields['rack'].choices = [] self.fields['device'].choices = [] self.fields['interface'].choices = []
class InterfaceConnectionForm(forms.ModelForm, BootstrapMixin): interface_a = forms.ChoiceField(choices=[], widget=SelectWithDisabled, label='Interface') rack_b = forms.ModelChoiceField(queryset=Rack.objects.all(), label='Rack', required=False, widget=forms.Select(attrs={'filter-for': 'device_b'})) device_b = forms.ModelChoiceField(queryset=Device.objects.all(), label='Device', required=False, widget=APISelect(api_url='/api/dcim/devices/?rack_id={{rack_b}}', attrs={'filter-for': 'interface_b'})) livesearch = forms.CharField(required=False, label='Device', widget=Livesearch( query_key='q', query_url='dcim-api:device_list', field_to_update='device_b') ) interface_b = forms.ModelChoiceField(queryset=Interface.objects.all(), label='Interface', widget=APISelect(api_url='/api/dcim/devices/{{device_b}}/interfaces/?type=physical', disabled_indicator='is_connected')) class Meta: model = InterfaceConnection fields = ['interface_a', 'rack_b', 'device_b', 'interface_b', 'livesearch', 'connection_status'] def __init__(self, device_a, *args, **kwargs): super(InterfaceConnectionForm, self).__init__(*args, **kwargs) self.fields['rack_b'].queryset = Rack.objects.filter(site=device_a.rack.site) # Initialize interface A choices device_a_interfaces = Interface.objects.filter(device=device_a).exclude(form_factor=IFACE_FF_VIRTUAL) \ .select_related('circuit', 'connected_as_a', 'connected_as_b') self.fields['interface_a'].choices = [ (iface.id, {'label': iface.name, 'disabled': iface.is_connected}) for iface in device_a_interfaces ] # Initialize device_b choices if rack_b is set if self.is_bound and self.data.get('rack_b'): self.fields['device_b'].queryset = Device.objects.filter(rack__pk=self.data['rack_b']) elif self.initial.get('rack_b'): self.fields['device_b'].queryset = Device.objects.filter(rack=self.initial['rack_b']) else: self.fields['device_b'].choices = [] # Initialize interface_b choices if device_b is set if self.is_bound: device_b_interfaces = Interface.objects.filter(device=self.data['device_b']) \ .exclude(form_factor=IFACE_FF_VIRTUAL).select_related('circuit', 'connected_as_a', 'connected_as_b') elif self.initial.get('device_b'): device_b_interfaces = Interface.objects.filter(device=self.initial['device_b']) \ .exclude(form_factor=IFACE_FF_VIRTUAL).select_related('circuit', 'connected_as_a', 'connected_as_b') else: device_b_interfaces = [] self.fields['interface_b'].choices = [ (iface.id, {'label': iface.name, 'disabled': iface.is_connected}) for iface in device_b_interfaces ]
class PowerPortConnectionForm(forms.ModelForm, BootstrapMixin): rack = forms.ModelChoiceField(queryset=Rack.objects.all(), label='Rack', required=False, widget=forms.Select(attrs={'filter-for': 'pdu'})) pdu = forms.ModelChoiceField(queryset=Device.objects.all(), label='PDU', required=False, widget=APISelect(api_url='/api/dcim/devices/?rack_id={{rack}}&is_pdu=True', attrs={'filter-for': 'power_outlet'})) livesearch = forms.CharField(required=False, label='PDU', widget=Livesearch( query_key='q', query_url='dcim-api:device_list', field_to_update='pdu') ) power_outlet = forms.ModelChoiceField(queryset=PowerOutlet.objects.all(), label='Outlet', widget=APISelect(api_url='/api/dcim/devices/{{pdu}}/power-outlets/', disabled_indicator='connected_port')) class Meta: model = PowerPort fields = ['rack', 'pdu', 'livesearch', 'power_outlet', 'connection_status'] labels = { 'power_outlet': 'Outlet', 'connection_status': 'Status', } def __init__(self, *args, **kwargs): super(PowerPortConnectionForm, self).__init__(*args, **kwargs) if not self.instance.pk: raise RuntimeError("PowerPortConnectionForm must be initialized with an existing PowerPort instance.") self.fields['rack'].queryset = Rack.objects.filter(site=self.instance.device.rack.site) self.fields['power_outlet'].required = True self.fields['connection_status'].choices = CONNECTION_STATUS_CHOICES # Initialize PDU choices if self.is_bound and self.data.get('rack'): self.fields['pdu'].queryset = Device.objects.filter(rack=self.data['rack'], device_type__is_pdu=True) elif self.initial.get('rack', None): self.fields['pdu'].queryset = Device.objects.filter(rack=self.initial['rack'], device_type__is_pdu=True) else: self.fields['pdu'].choices = [] # Initialize power outlet choices if self.is_bound: self.fields['power_outlet'].queryset = PowerOutlet.objects.filter(device__pk=self.data['pdu']) elif self.initial.get('pdu', None): self.fields['power_outlet'].queryset = PowerOutlet.objects.filter(device__pk=self.initial['pdu']) else: self.fields['power_outlet'].choices = []
class PowerOutletConnectionForm(forms.Form, BootstrapMixin): rack = forms.ModelChoiceField(queryset=Rack.objects.all(), label='Rack', required=False, widget=forms.Select(attrs={'filter-for': 'device'})) device = forms.ModelChoiceField(queryset=Device.objects.all(), label='Device', required=False, widget=APISelect(api_url='/api/dcim/devices/?rack_id={{rack}}', attrs={'filter-for': 'port'})) livesearch = forms.CharField(required=False, label='Device', widget=Livesearch( query_key='q', query_url='dcim-api:device_list', field_to_update='device') ) port = forms.ModelChoiceField(queryset=PowerPort.objects.all(), label='Port', widget=APISelect(api_url='/api/dcim/devices/{{device}}/power-ports/', disabled_indicator='power_outlet')) connection_status = forms.BooleanField(required=False, initial=CONNECTION_STATUS_CONNECTED, label='Status', widget=forms.Select(choices=CONNECTION_STATUS_CHOICES)) class Meta: fields = ['rack', 'device', 'livesearch', 'port', 'connection_status'] labels = { 'connection_status': 'Status', } def __init__(self, poweroutlet, *args, **kwargs): super(PowerOutletConnectionForm, self).__init__(*args, **kwargs) self.fields['rack'].queryset = Rack.objects.filter(site=poweroutlet.device.rack.site) # Initialize device choices if self.is_bound and self.data.get('rack'): self.fields['device'].queryset = Device.objects.filter(rack=self.data['rack']) elif self.initial.get('rack', None): self.fields['device'].queryset = Device.objects.filter(rack=self.initial['rack']) else: self.fields['device'].choices = [] # Initialize port choices if self.is_bound: self.fields['port'].queryset = PowerPort.objects.filter(device__pk=self.data['device']) elif self.initial.get('device', None): self.fields['port'].queryset = PowerPort.objects.filter(device_pk=self.initial['device']) else: self.fields['port'].choices = []
class IPAddressForm(BootstrapMixin, TenancyForm, ReturnURLForm, CustomFieldForm): interface = forms.ModelChoiceField(queryset=Interface.objects.all(), required=False) nat_site = forms.ModelChoiceField( queryset=Site.objects.all(), required=False, label='Site', widget=forms.Select(attrs={'filter-for': 'nat_rack'})) nat_rack = ChainedModelChoiceField( queryset=Rack.objects.all(), chains=(('site', 'nat_site'), ), required=False, label='Rack', widget=APISelect(api_url='/api/dcim/racks/?site_id={{nat_site}}', display_field='display_name', attrs={ 'filter-for': 'nat_device', 'nullable': 'true' })) nat_device = ChainedModelChoiceField( queryset=Device.objects.all(), chains=( ('site', 'nat_site'), ('rack', 'nat_rack'), ), required=False, label='Device', widget=APISelect( api_url= '/api/dcim/devices/?site_id={{nat_site}}&rack_id={{nat_rack}}', display_field='display_name', attrs={'filter-for': 'nat_inside'})) nat_inside = ChainedModelChoiceField( queryset=IPAddress.objects.all(), chains=(('interface__device', 'nat_device'), ), required=False, label='IP Address', widget=APISelect( api_url='/api/ipam/ip-addresses/?device_id={{nat_device}}', display_field='address')) livesearch = forms.CharField(required=False, label='Search', widget=Livesearch( query_key='q', query_url='ipam-api:ipaddress-list', field_to_update='nat_inside', obj_label='address')) primary_for_parent = forms.BooleanField( required=False, label='Make this the primary IP for the device/VM') class Meta: model = IPAddress fields = [ 'address', 'vrf', 'status', 'role', 'description', 'interface', 'primary_for_parent', 'nat_site', 'nat_rack', 'nat_inside', 'tenant_group', 'tenant', ] def __init__(self, *args, **kwargs): # Initialize helper selectors instance = kwargs.get('instance') initial = kwargs.get('initial', {}).copy() if instance and instance.nat_inside and instance.nat_inside.device is not None: initial['nat_site'] = instance.nat_inside.device.site initial['nat_rack'] = instance.nat_inside.device.rack initial['nat_device'] = instance.nat_inside.device kwargs['initial'] = initial super(IPAddressForm, self).__init__(*args, **kwargs) self.fields['vrf'].empty_label = 'Global' # Limit interface selections to those belonging to the parent device/VM if self.instance and self.instance.interface: self.fields['interface'].queryset = Interface.objects.filter( device=self.instance.interface.device, virtual_machine=self.instance.interface.virtual_machine) else: self.fields['interface'].choices = [] # Initialize primary_for_parent if IP address is already assigned if self.instance.pk and self.instance.interface is not None: parent = self.instance.interface.parent 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(IPAddressForm, self).clean() # Primary IP assignment is only available if an interface has been assigned. if self.cleaned_data.get('primary_for_parent' ) and not self.cleaned_data.get('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(IPAddressForm, self).save(*args, **kwargs) # Assign this IPAddress as the primary for the associated Device. if self.cleaned_data['primary_for_parent']: parent = self.cleaned_data['interface'].parent if ipaddress.address.version == 4: parent.primary_ip4 = ipaddress else: parent.primary_ip6 = ipaddress parent.save() # Clear assignment as primary for device if set. else: try: if ipaddress.address.version == 4: device = ipaddress.primary_ip4_for device.primary_ip4 = None else: device = ipaddress.primary_ip6_for device.primary_ip6 = None device.save() except Device.DoesNotExist: pass return ipaddress
class CircuitForm(forms.ModelForm, BootstrapMixin): site = forms.ModelChoiceField( queryset=Site.objects.all(), widget=forms.Select(attrs={'filter-for': 'rack'})) rack = forms.ModelChoiceField( queryset=Rack.objects.all(), required=False, label='Rack', widget=APISelect(api_url='/api/dcim/racks/?site_id={{site}}', attrs={'filter-for': 'device'})) device = forms.ModelChoiceField( queryset=Device.objects.all(), required=False, label='Device', widget=APISelect(api_url='/api/dcim/devices/?rack_id={{rack}}', attrs={'filter-for': 'interface'})) livesearch = forms.CharField(required=False, label='Device', widget=Livesearch( query_key='q', query_url='dcim-api:device_list', field_to_update='device')) interface = forms.ModelChoiceField( queryset=Interface.objects.all(), required=False, label='Interface', widget=APISelect( api_url='/api/dcim/devices/{{device}}/interfaces/?type=physical', disabled_indicator='is_connected')) comments = CommentField() class Meta: model = Circuit fields = [ 'cid', 'type', 'provider', 'tenant', 'site', 'rack', 'device', 'livesearch', 'interface', 'install_date', 'port_speed', 'upstream_speed', 'commit_rate', 'xconnect_id', 'pp_info', 'comments' ] help_texts = { 'cid': "Unique circuit ID", 'install_date': "Format: YYYY-MM-DD", 'port_speed': "Physical circuit speed", 'commit_rate': "Commited rate", 'xconnect_id': "ID of the local cross-connect", 'pp_info': "Patch panel ID and port number(s)" } def __init__(self, *args, **kwargs): super(CircuitForm, self).__init__(*args, **kwargs) # If this circuit has been assigned to an interface, initialize rack and device if self.instance.interface: self.initial['rack'] = self.instance.interface.device.rack self.initial['device'] = self.instance.interface.device # Limit rack choices if self.is_bound: self.fields['rack'].queryset = Rack.objects.filter( site__pk=self.data['site']) elif self.initial.get('site'): self.fields['rack'].queryset = Rack.objects.filter( site=self.initial['site']) else: self.fields['rack'].choices = [] # Limit device choices if self.is_bound and self.data.get('rack'): self.fields['device'].queryset = Device.objects.filter( rack=self.data['rack']) elif self.initial.get('rack'): self.fields['device'].queryset = Device.objects.filter( rack=self.initial['rack']) else: self.fields['device'].choices = [] # Limit interface choices if self.is_bound and self.data.get('device'): interfaces = Interface.objects.filter(device=self.data['device'])\ .exclude(form_factor=IFACE_FF_VIRTUAL).select_related('circuit', 'connected_as_a', 'connected_as_b') self.fields['interface'].widget.attrs['initial'] = self.data.get( 'interface') elif self.initial.get('device'): interfaces = Interface.objects.filter(device=self.initial['device'])\ .exclude(form_factor=IFACE_FF_VIRTUAL).select_related('circuit', 'connected_as_a', 'connected_as_b') self.fields['interface'].widget.attrs[ 'initial'] = self.initial.get('interface') else: interfaces = [] self.fields['interface'].choices = [(iface.id, { 'label': iface.name, 'disabled': iface.is_connected and iface.id != self.fields['interface'].widget.attrs.get('initial'), }) for iface in interfaces]
class IPAddressForm(BootstrapMixin, ReturnURLForm, CustomFieldForm): interface_site = forms.ModelChoiceField( queryset=Site.objects.all(), required=False, label='Site', widget=forms.Select(attrs={'filter-for': 'interface_rack'})) interface_rack = forms.ModelChoiceField( queryset=Rack.objects.all(), required=False, label='Rack', widget=APISelect(api_url='/api/dcim/racks/?site_id={{interface_site}}', display_field='display_name', attrs={ 'filter-for': 'interface_device', 'nullable': 'true' })) interface_device = forms.ModelChoiceField( queryset=Device.objects.all(), required=False, label='Device', widget=APISelect( api_url= '/api/dcim/devices/?site_id={{interface_site}}&rack_id={{interface_rack}}', display_field='display_name', attrs={'filter-for': 'interface'})) nat_site = forms.ModelChoiceField( queryset=Site.objects.all(), required=False, label='Site', widget=forms.Select(attrs={'filter-for': 'nat_device'})) nat_device = forms.ModelChoiceField( queryset=Device.objects.all(), required=False, label='Device', widget=APISelect(api_url='/api/dcim/devices/?site_id={{nat_site}}', display_field='display_name', attrs={'filter-for': 'nat_inside'})) livesearch = forms.CharField(required=False, label='IP Address', widget=Livesearch( query_key='q', query_url='ipam-api:ipaddress-list', field_to_update='nat_inside', obj_label='address')) primary_for_device = forms.BooleanField( required=False, label='Make this the primary IP for the device') class Meta: model = IPAddress fields = [ 'address', 'vrf', 'tenant', 'status', 'description', 'interface', 'primary_for_device', 'nat_inside' ] widgets = { 'interface': APISelect( api_url='/api/dcim/interfaces/?device_id={{interface_device}}' ), 'nat_inside': APISelect( api_url='/api/ipam/ip-addresses/?device_id={{nat_device}}', display_field='address') } def __init__(self, *args, **kwargs): super(IPAddressForm, self).__init__(*args, **kwargs) self.fields['vrf'].empty_label = 'Global' # If an interface has been assigned, initialize site, rack, and device if self.instance.interface: self.initial[ 'interface_site'] = self.instance.interface.device.site self.initial[ 'interface_rack'] = self.instance.interface.device.rack self.initial['interface_device'] = self.instance.interface.device # Limit rack choices if self.is_bound and self.data.get('interface_site'): self.fields['interface_rack'].queryset = Rack.objects.filter( site__pk=self.data['interface_site']) elif self.initial.get('interface_site'): self.fields['interface_rack'].queryset = Rack.objects.filter( site=self.initial['interface_site']) else: self.fields['interface_rack'].choices = [] # Limit device choices if self.is_bound and self.data.get('interface_rack'): self.fields['interface_device'].queryset = Device.objects.filter( rack=self.data['interface_rack']) elif self.initial.get('interface_rack'): self.fields['interface_device'].queryset = Device.objects.filter( rack=self.initial['interface_rack']) else: self.fields['interface_device'].choices = [] # Limit interface choices if self.is_bound and self.data.get('interface_device'): self.fields['interface'].queryset = Interface.objects.filter( device=self.data['interface_device']) elif self.initial.get('interface_device'): self.fields['interface'].queryset = Interface.objects.filter( device=self.initial['interface_device']) else: self.fields['interface'].choices = [] # Initialize primary_for_device if IP address is already assigned if self.instance.interface is not None: device = self.instance.interface.device if (self.instance.address.version == 4 and device.primary_ip4 == self.instance or self.instance.address.version == 6 and device.primary_ip6 == self.instance): self.initial['primary_for_device'] = True if self.instance.nat_inside: nat_inside = self.instance.nat_inside # If the IP is assigned to an interface, populate site/device fields accordingly if self.instance.nat_inside.interface: self.initial[ 'nat_site'] = self.instance.nat_inside.interface.device.site.pk self.initial[ 'nat_device'] = self.instance.nat_inside.interface.device.pk self.fields['nat_device'].queryset = Device.objects.filter( site=nat_inside.interface.device.site) self.fields['nat_inside'].queryset = IPAddress.objects.filter( interface__device=nat_inside.interface.device) else: self.fields['nat_inside'].queryset = IPAddress.objects.filter( pk=nat_inside.pk) else: # Initialize nat_device choices if nat_site is set if self.is_bound and self.data.get('nat_site'): self.fields['nat_device'].queryset = Device.objects.filter( site__pk=self.data['nat_site']) elif self.initial.get('nat_site'): self.fields['nat_device'].queryset = Device.objects.filter( site=self.initial['nat_site']) else: self.fields['nat_device'].choices = [] # Initialize nat_inside choices if nat_device is set if self.is_bound and self.data.get('nat_device'): self.fields['nat_inside'].queryset = IPAddress.objects.filter( interface__device__pk=self.data['nat_device']) elif self.initial.get('nat_device'): self.fields['nat_inside'].queryset = IPAddress.objects.filter( interface__device__pk=self.initial['nat_device']) else: self.fields['nat_inside'].choices = [] def clean(self): super(IPAddressForm, self).clean() # Primary IP assignment is only available if an interface has been assigned. if self.cleaned_data.get('primary_for_device' ) and not self.cleaned_data.get('interface'): self.add_error( 'primary_for_device', "Only IP addresses assigned to an interface can be designated as primary IPs." ) def save(self, *args, **kwargs): ipaddress = super(IPAddressForm, self).save(*args, **kwargs) # Assign this IPAddress as the primary for the associated Device. if self.cleaned_data['primary_for_device']: device = self.cleaned_data['interface'].device if ipaddress.address.version == 4: device.primary_ip4 = ipaddress else: device.primary_ip6 = ipaddress device.save() # Clear assignment as primary for device if set. else: try: if ipaddress.address.version == 4: device = ipaddress.primary_ip4_for device.primary_ip4 = None else: device = ipaddress.primary_ip6_for device.primary_ip6 = None device.save() except Device.DoesNotExist: pass return ipaddress
class CircuitTerminationForm(BootstrapMixin, ChainedFieldsMixin, forms.ModelForm): site = forms.ModelChoiceField( queryset=Site.objects.all(), widget=forms.Select(attrs={'filter-for': 'rack'})) rack = ChainedModelChoiceField( queryset=Rack.objects.all(), chains={'site': 'site'}, required=False, label='Rack', widget=APISelect(api_url='/api/dcim/racks/?site_id={{site}}', attrs={ 'filter-for': 'device', 'nullable': 'true' })) device = ChainedModelChoiceField( queryset=Device.objects.all(), chains={ 'site': 'site', 'rack': 'rack' }, required=False, label='Device', widget=APISelect( api_url='/api/dcim/devices/?site_id={{site}}&rack_id={{rack}}', display_field='display_name', attrs={'filter-for': 'interface'})) livesearch = forms.CharField(required=False, label='Device', widget=Livesearch( query_key='q', query_url='dcim-api:device-list', field_to_update='device')) interface = ChainedModelChoiceField( queryset=Interface.objects.exclude( form_factor__in=VIRTUAL_IFACE_TYPES).select_related( 'circuit_termination', 'connected_as_a', 'connected_as_b'), chains={'device': 'device'}, required=False, label='Interface', widget=APISelect( api_url='/api/dcim/interfaces/?device_id={{device}}&type=physical', disabled_indicator='is_connected')) class Meta: model = CircuitTermination fields = [ 'term_side', 'site', 'rack', 'device', 'livesearch', 'interface', 'port_speed', 'upstream_speed', 'xconnect_id', 'pp_info' ] help_texts = { 'port_speed': "Physical circuit speed", 'xconnect_id': "ID of the local cross-connect", 'pp_info': "Patch panel ID and port number(s)" } widgets = { 'term_side': forms.HiddenInput(), } def __init__(self, *args, **kwargs): # Initialize helper selectors instance = kwargs.get('instance') if instance and instance.interface is not None: initial = kwargs.get('initial', {}) initial['rack'] = instance.interface.device.rack initial['device'] = instance.interface.device kwargs['initial'] = initial super(CircuitTerminationForm, self).__init__(*args, **kwargs) # Mark connected interfaces as disabled self.fields['interface'].choices = [(iface.id, { 'label': iface.name, 'disabled': iface.is_connected }) for iface in self.fields['interface'].queryset]
class IPAddressForm(BootstrapMixin, ReturnURLForm, CustomFieldForm): interface_site = forms.ModelChoiceField( queryset=Site.objects.all(), required=False, label='Site', widget=forms.Select( attrs={'filter-for': 'interface_rack'} ) ) interface_rack = forms.ModelChoiceField( queryset=Rack.objects.all(), required=False, label='Rack', widget=APISelect( api_url='/api/dcim/racks/?site_id={{interface_site}}', display_field='display_name', attrs={'filter-for': 'interface_device'} ) ) interface_device = forms.ModelChoiceField( queryset=Device.objects.all(), required=False, label='Device', widget=APISelect( api_url='/api/dcim/devices/?site_id={{interface_site}}&rack_id={{interface_rack}}', display_field='display_name', attrs={'filter-for': 'interface'} ) ) nat_site = forms.ModelChoiceField( queryset=Site.objects.all(), required=False, label='Site', widget=forms.Select( attrs={'filter-for': 'nat_device'} ) ) nat_device = forms.ModelChoiceField( queryset=Device.objects.all(), required=False, label='Device', widget=APISelect( api_url='/api/dcim/devices/?site_id={{nat_site}}', display_field='display_name', attrs={'filter-for': 'nat_inside'} ) ) livesearch = forms.CharField( required=False, label='IP Address', widget=Livesearch( query_key='q', query_url='ipam-api:ipaddress_list', field_to_update='nat_inside', obj_label='address' ) ) class Meta: model = IPAddress fields = ['address', 'vrf', 'tenant', 'status', 'interface', 'nat_inside', 'description'] widgets = { 'interface': APISelect(api_url='/api/dcim/devices/{{interface_device}}/interfaces/'), 'nat_inside': APISelect(api_url='/api/ipam/ip-addresses/?device_id={{nat_device}}', display_field='address') } def __init__(self, *args, **kwargs): super(IPAddressForm, self).__init__(*args, **kwargs) self.fields['vrf'].empty_label = 'Global' # If an interface has been assigned, initialize site, rack, and device if self.instance.interface: self.initial['interface_site'] = self.instance.interface.device.site self.initial['interface_rack'] = self.instance.interface.device.rack self.initial['interface_device'] = self.instance.interface.device # Limit rack choices if self.is_bound and self.data.get('interface_site'): self.fields['interface_rack'].queryset = Rack.objects.filter(site__pk=self.data['interface_site']) elif self.initial.get('interface_site'): self.fields['interface_rack'].queryset = Rack.objects.filter(site=self.initial['interface_site']) else: self.fields['interface_rack'].choices = [] # Limit device choices if self.is_bound and self.data.get('interface_rack'): self.fields['interface_device'].queryset = Device.objects.filter(rack=self.data['interface_rack']) elif self.initial.get('interface_rack'): self.fields['interface_device'].queryset = Device.objects.filter(rack=self.initial['interface_rack']) else: self.fields['interface_device'].choices = [] # Limit interface choices if self.is_bound and self.data.get('interface_device'): self.fields['interface'].queryset = Interface.objects.filter(device=self.data['interface_device']) elif self.initial.get('interface_device'): self.fields['interface'].queryset = Interface.objects.filter(device=self.initial['interface_device']) else: self.fields['interface'].choices = [] if self.instance.nat_inside: nat_inside = self.instance.nat_inside # If the IP is assigned to an interface, populate site/device fields accordingly if self.instance.nat_inside.interface: self.initial['nat_site'] = self.instance.nat_inside.interface.device.site.pk self.initial['nat_device'] = self.instance.nat_inside.interface.device.pk self.fields['nat_device'].queryset = Device.objects.filter( site=nat_inside.interface.device.site ) self.fields['nat_inside'].queryset = IPAddress.objects.filter( interface__device=nat_inside.interface.device ) else: self.fields['nat_inside'].queryset = IPAddress.objects.filter(pk=nat_inside.pk) else: # Initialize nat_device choices if nat_site is set if self.is_bound and self.data.get('nat_site'): self.fields['nat_device'].queryset = Device.objects.filter(site__pk=self.data['nat_site']) elif self.initial.get('nat_site'): self.fields['nat_device'].queryset = Device.objects.filter(site=self.initial['nat_site']) else: self.fields['nat_device'].choices = [] # Initialize nat_inside choices if nat_device is set if self.is_bound and self.data.get('nat_device'): self.fields['nat_inside'].queryset = IPAddress.objects.filter( interface__device__pk=self.data['nat_device']) elif self.initial.get('nat_device'): self.fields['nat_inside'].queryset = IPAddress.objects.filter( interface__device__pk=self.initial['nat_device']) else: self.fields['nat_inside'].choices = []
class CircuitTerminationForm(BootstrapMixin, forms.ModelForm): site = forms.ModelChoiceField( queryset=Site.objects.all(), widget=forms.Select(attrs={'filter-for': 'rack'})) rack = forms.ModelChoiceField( queryset=Rack.objects.all(), required=False, label='Rack', widget=APISelect(api_url='/api/dcim/racks/?site_id={{site}}', attrs={ 'filter-for': 'device', 'nullable': 'true' })) device = forms.ModelChoiceField( queryset=Device.objects.all(), required=False, label='Device', widget=APISelect( api_url='/api/dcim/devices/?site_id={{site}}&rack_id={{rack}}', display_field='display_name', attrs={'filter-for': 'interface'})) livesearch = forms.CharField(required=False, label='Device', widget=Livesearch( query_key='q', query_url='dcim-api:device-list', field_to_update='device')) interface = forms.ModelChoiceField( queryset=Interface.objects.all(), required=False, label='Interface', widget=APISelect( api_url='/api/dcim/interfaces/?device_id={{device}}&type=physical', disabled_indicator='is_connected')) class Meta: model = CircuitTermination fields = [ 'term_side', 'site', 'rack', 'device', 'livesearch', 'interface', 'port_speed', 'upstream_speed', 'xconnect_id', 'pp_info' ] help_texts = { 'port_speed': "Physical circuit speed", 'xconnect_id': "ID of the local cross-connect", 'pp_info': "Patch panel ID and port number(s)" } widgets = { 'term_side': forms.HiddenInput(), } def __init__(self, *args, **kwargs): super(CircuitTerminationForm, self).__init__(*args, **kwargs) # If an interface has been assigned, initialize rack and device if self.instance.interface: self.initial['rack'] = self.instance.interface.device.rack self.initial['device'] = self.instance.interface.device # Limit rack choices if self.is_bound: self.fields['rack'].queryset = Rack.objects.filter( site__pk=self.data['site']) elif self.initial.get('site'): self.fields['rack'].queryset = Rack.objects.filter( site=self.initial['site']) else: self.fields['rack'].choices = [] # Limit device choices if self.is_bound and self.data.get('rack'): self.fields['device'].queryset = Device.objects.filter( rack=self.data['rack']) elif self.initial.get('rack'): self.fields['device'].queryset = Device.objects.filter( rack=self.initial['rack']) else: self.fields['device'].choices = [] # Limit interface choices if self.is_bound and self.data.get('device'): interfaces = Interface.objects.filter( device=self.data['device']).exclude( form_factor__in=VIRTUAL_IFACE_TYPES).select_related( 'circuit_termination', 'connected_as_a', 'connected_as_b') self.fields['interface'].widget.attrs['initial'] = self.data.get( 'interface') elif self.initial.get('device'): interfaces = Interface.objects.filter( device=self.initial['device']).exclude( form_factor__in=VIRTUAL_IFACE_TYPES).select_related( 'circuit_termination', 'connected_as_a', 'connected_as_b') self.fields['interface'].widget.attrs[ 'initial'] = self.initial.get('interface') else: interfaces = [] self.fields['interface'].choices = [(iface.id, { 'label': iface.name, 'disabled': iface.is_connected and iface.id != self.fields['interface'].widget.attrs.get('initial'), }) for iface in interfaces]