mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-23 04:22:01 -06:00
Closes #647: Extend form used when assigning an IP to a device
This commit is contained in:
parent
084b86cab1
commit
f2137683f9
@ -1228,15 +1228,12 @@ class InterfaceConnectionFilterForm(forms.Form, BootstrapMixin):
|
||||
# IP addresses
|
||||
#
|
||||
|
||||
class IPAddressForm(forms.ModelForm, BootstrapMixin):
|
||||
class IPAddressForm(BootstrapMixin, CustomFieldForm):
|
||||
set_as_primary = forms.BooleanField(label='Set as primary IP for device', required=False)
|
||||
|
||||
class Meta:
|
||||
model = IPAddress
|
||||
fields = ['address', 'vrf', 'interface', 'set_as_primary']
|
||||
help_texts = {
|
||||
'address': 'IPv4 or IPv6 address (with mask)'
|
||||
}
|
||||
fields = ['address', 'vrf', 'tenant', 'status', 'interface', 'description']
|
||||
|
||||
def __init__(self, device, *args, **kwargs):
|
||||
|
||||
|
@ -572,7 +572,8 @@ def device(request, pk):
|
||||
secrets = device.secrets.all()
|
||||
|
||||
# Find all IP addresses assigned to this device
|
||||
ip_addresses = IPAddress.objects.filter(interface__device=device).select_related('interface').order_by('address')
|
||||
ip_addresses = IPAddress.objects.filter(interface__device=device).select_related('interface', 'vrf')\
|
||||
.order_by('address')
|
||||
|
||||
# Find any related devices for convenient linking in the UI
|
||||
related_devices = []
|
||||
@ -1530,6 +1531,7 @@ def ipaddress_assign(request, pk):
|
||||
ipaddress = form.save(commit=False)
|
||||
ipaddress.interface = form.cleaned_data['interface']
|
||||
ipaddress.save()
|
||||
form.save_custom_fields()
|
||||
messages.success(request, u"Added new IP address {} to interface {}.".format(ipaddress, ipaddress.interface))
|
||||
|
||||
if form.cleaned_data['set_as_primary']:
|
||||
|
@ -284,16 +284,12 @@ class IPAddressForm(BootstrapMixin, CustomFieldForm):
|
||||
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', 'status', 'nat_device', 'nat_inside', 'description']
|
||||
help_texts = {
|
||||
'address': "IPv4 or IPv6 address and mask",
|
||||
'vrf': "VRF (if applicable)",
|
||||
fields = ['address', 'vrf', 'tenant', 'status', 'nat_inside', 'description']
|
||||
widgets ={
|
||||
'nat_inside': APISelect(api_url='/api/ipam/ip-addresses/?device_id={{nat_device}}', display_field='address')
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
27
netbox/ipam/migrations/0010_ipaddress_help_texts.py
Normal file
27
netbox/ipam/migrations/0010_ipaddress_help_texts.py
Normal file
@ -0,0 +1,27 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10 on 2016-11-01 17:46
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import ipam.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('ipam', '0009_ipaddress_add_status'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='ipaddress',
|
||||
name='address',
|
||||
field=ipam.fields.IPAddressField(help_text=b'IPv4 or IPv6 address (with mask)'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='ipaddress',
|
||||
name='nat_inside',
|
||||
field=models.OneToOneField(blank=True, help_text=b'The IP for which this address is the "outside" IP', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='nat_outside', to='ipam.IPAddress', verbose_name=b'NAT (Inside)'),
|
||||
),
|
||||
]
|
@ -346,7 +346,7 @@ class IPAddress(CreatedUpdatedModel, CustomFieldModel):
|
||||
which has a NAT outside IP, that Interface's Device can use either the inside or outside IP as its primary IP.
|
||||
"""
|
||||
family = models.PositiveSmallIntegerField(choices=AF_CHOICES, editable=False)
|
||||
address = IPAddressField()
|
||||
address = IPAddressField(help_text="IPv4 or IPv6 address (with mask)")
|
||||
vrf = models.ForeignKey('VRF', related_name='ip_addresses', on_delete=models.PROTECT, blank=True, null=True,
|
||||
verbose_name='VRF')
|
||||
tenant = models.ForeignKey(Tenant, related_name='ip_addresses', blank=True, null=True, on_delete=models.PROTECT)
|
||||
@ -354,7 +354,8 @@ class IPAddress(CreatedUpdatedModel, CustomFieldModel):
|
||||
interface = models.ForeignKey(Interface, related_name='ip_addresses', on_delete=models.CASCADE, blank=True,
|
||||
null=True)
|
||||
nat_inside = models.OneToOneField('self', related_name='nat_outside', on_delete=models.SET_NULL, blank=True,
|
||||
null=True, verbose_name='NAT IP (inside)')
|
||||
null=True, verbose_name='NAT (Inside)',
|
||||
help_text="The IP for which this address is the \"outside\" IP")
|
||||
description = models.CharField(max_length=100, blank=True)
|
||||
custom_field_values = GenericRelation(CustomFieldValue, content_type_field='obj_type', object_id_field='obj_id')
|
||||
|
||||
|
@ -2,6 +2,9 @@
|
||||
<td>
|
||||
<a href="{% url 'ipam:ipaddress' pk=ip.pk %}">{{ ip }}</a>
|
||||
</td>
|
||||
<td>
|
||||
{{ ip.vrf|default:"Global" }}
|
||||
</td>
|
||||
<td>{{ ip.interface }}</td>
|
||||
<td>
|
||||
{% if device.primary_ip4 == ip or device.primary_ip6 == ip %}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{% extends '_base.html' %}
|
||||
{% load form_helpers %}
|
||||
|
||||
{% block title %}Add an IP Address{% endblock %}
|
||||
{% block title %}Assign an IP Address{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form action="." method="post" class="form form-horizontal">
|
||||
@ -18,10 +18,34 @@
|
||||
{% endif %}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
Add an IP Address
|
||||
<strong>IP Address</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{% render_form form %}
|
||||
{% render_field form.address %}
|
||||
{% render_field form.vrf %}
|
||||
{% render_field form.tenant %}
|
||||
{% render_field form.status %}
|
||||
{% render_field form.description %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>Interface Assignment</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">Device</label>
|
||||
<div class="col-md-9">
|
||||
<p class="form-control-static">{{ device }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% render_field form.interface %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading"><strong>Custom Fields</strong></div>
|
||||
<div class="panel-body">
|
||||
{% render_custom_fields form %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
Loading…
Reference in New Issue
Block a user