mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-02 05:46:25 -06:00
Merge b47b1743f7
into b42dab3eef
This commit is contained in:
commit
bf9233bedb
@ -1599,7 +1599,9 @@ def ipaddress_assign(request, pk):
|
|||||||
return redirect('dcim:device', pk=device.pk)
|
return redirect('dcim:device', pk=device.pk)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
form = forms.IPAddressForm(device)
|
form = forms.IPAddressForm(device, initial={
|
||||||
|
'interface': request.GET.get('interface', None)
|
||||||
|
})
|
||||||
|
|
||||||
return render(request, 'dcim/ipaddress_assign.html', {
|
return render(request, 'dcim/ipaddress_assign.html', {
|
||||||
'device': device,
|
'device': device,
|
||||||
|
@ -308,6 +308,8 @@ class PrefixFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class IPAddressForm(BootstrapMixin, CustomFieldForm):
|
class IPAddressForm(BootstrapMixin, CustomFieldForm):
|
||||||
|
interface = forms.ModelChoiceField(queryset=Interface.objects.all(), label='Interface',
|
||||||
|
widget=APISelect(api_url='/api/dcim/devices/{{device}}/interfaces/'))
|
||||||
nat_site = forms.ModelChoiceField(queryset=Site.objects.all(), required=False, label='Site',
|
nat_site = forms.ModelChoiceField(queryset=Site.objects.all(), required=False, label='Site',
|
||||||
widget=forms.Select(attrs={'filter-for': 'nat_device'}))
|
widget=forms.Select(attrs={'filter-for': 'nat_device'}))
|
||||||
nat_device = forms.ModelChoiceField(queryset=Device.objects.all(), required=False, label='Device',
|
nat_device = forms.ModelChoiceField(queryset=Device.objects.all(), required=False, label='Device',
|
||||||
@ -317,10 +319,11 @@ class IPAddressForm(BootstrapMixin, CustomFieldForm):
|
|||||||
livesearch = forms.CharField(required=False, label='IP Address', widget=Livesearch(
|
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')
|
query_key='q', query_url='ipam-api:ipaddress_list', field_to_update='nat_inside', obj_label='address')
|
||||||
)
|
)
|
||||||
|
return_url = forms.CharField(required=False, widget=forms.HiddenInput())
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IPAddress
|
model = IPAddress
|
||||||
fields = ['address', 'vrf', 'tenant', 'status', 'nat_inside', 'description']
|
fields = ['address', 'vrf', 'tenant', 'status', 'interface', 'nat_inside', 'description']
|
||||||
widgets = {
|
widgets = {
|
||||||
'nat_inside': APISelect(api_url='/api/ipam/ip-addresses/?device_id={{nat_device}}', display_field='address')
|
'nat_inside': APISelect(api_url='/api/ipam/ip-addresses/?device_id={{nat_device}}', display_field='address')
|
||||||
}
|
}
|
||||||
@ -330,6 +333,12 @@ class IPAddressForm(BootstrapMixin, CustomFieldForm):
|
|||||||
|
|
||||||
self.fields['vrf'].empty_label = 'Global'
|
self.fields['vrf'].empty_label = 'Global'
|
||||||
|
|
||||||
|
interfaces = Interface.objects.filter(device=self.instance.device)
|
||||||
|
|
||||||
|
self.fields['interface'].choices = [
|
||||||
|
(iface.id, {'label': iface.name, 'disabled': ''}) for iface in interfaces
|
||||||
|
]
|
||||||
|
|
||||||
if self.instance.nat_inside:
|
if self.instance.nat_inside:
|
||||||
|
|
||||||
nat_inside = self.instance.nat_inside
|
nat_inside = self.instance.nat_inside
|
||||||
|
@ -645,7 +645,7 @@ class IPAddressEditView(PermissionRequiredMixin, ObjectEditView):
|
|||||||
permission_required = 'ipam.change_ipaddress'
|
permission_required = 'ipam.change_ipaddress'
|
||||||
model = IPAddress
|
model = IPAddress
|
||||||
form_class = forms.IPAddressForm
|
form_class = forms.IPAddressForm
|
||||||
fields_initial = ['address', 'vrf']
|
fields_initial = ['address', 'vrf', 'return_url']
|
||||||
template_name = 'ipam/ipaddress_edit.html'
|
template_name = 'ipam/ipaddress_edit.html'
|
||||||
default_return_url = 'ipam:ipaddress_list'
|
default_return_url = 'ipam:ipaddress_list'
|
||||||
|
|
||||||
|
@ -61,6 +61,11 @@
|
|||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if perms.ipam.add_ipaddress %}
|
||||||
|
<a href="{% url 'dcim:ipaddress_assign' pk=device.pk %}?interface={{ iface.pk }}" class="btn btn-xs btn-primary">
|
||||||
|
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
{% if perms.dcim.change_interface %}
|
{% if perms.dcim.change_interface %}
|
||||||
{% if not iface.is_virtual %}
|
{% if not iface.is_virtual %}
|
||||||
{% if iface.connection %}
|
{% if iface.connection %}
|
||||||
@ -74,7 +79,7 @@
|
|||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="{% url 'dcim:interfaceconnection_delete' pk=iface.connection.pk %}?device={{ device.pk }}" class="btn btn-danger btn-xs" title="Delete connection">
|
<a href="{% url 'dcim:interfaceconnection_delete' pk=iface.connection.pk %}?device={{ device.pk }}" class="btn btn-danger btn-xs" title="Delete connection">
|
||||||
<i class="glyphicon glyphicon-remove" aria-hidden="true"></i>
|
<i class="glyphicon glyphicon-resize-full" aria-hidden="true"></i>
|
||||||
</a>
|
</a>
|
||||||
{% elif iface.circuit_termination and perms.circuits.change_circuittermination %}
|
{% elif iface.circuit_termination and perms.circuits.change_circuittermination %}
|
||||||
<button class="btn btn-warning btn-xs interface-toggle connected" disabled="disabled" title="Circuits cannot be marked as planned or connected">
|
<button class="btn btn-warning btn-xs interface-toggle connected" disabled="disabled" title="Circuits cannot be marked as planned or connected">
|
||||||
@ -85,7 +90,7 @@
|
|||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="{% url 'dcim:interfaceconnection_add' pk=device.pk %}?interface_a={{ iface.pk }}" class="btn btn-success btn-xs" title="Connect">
|
<a href="{% url 'dcim:interfaceconnection_add' pk=device.pk %}?interface_a={{ iface.pk }}" class="btn btn-success btn-xs" title="Connect">
|
||||||
<i class="glyphicon glyphicon-plus" aria-hidden="true"></i>
|
<i class="glyphicon glyphicon-resize-small" aria-hidden="true"></i>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -106,3 +111,19 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
{% if ip_addresses %}
|
||||||
|
{% for ip in ip_addresses %}
|
||||||
|
{% if ip.interface_id == iface.id %}
|
||||||
|
<tr style="background: #eff">
|
||||||
|
<td></td>
|
||||||
|
<td><a href="{% url 'ipam:ipaddress' pk=ip.pk %}">{{ ip }}</a></td>
|
||||||
|
<td>{{ ip.vrf|default:"Global" }}</td>
|
||||||
|
<td>{% if device.primary_ip4 == ip or device.primary_ip6 == ip %}
|
||||||
|
<span class="label label-success">Primary</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td colspan="2">{{ ip.description }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
@ -12,6 +12,11 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
|
{% if perms.ipam.change_ipaddress %}
|
||||||
|
<a href="{% url 'ipam:ipaddress_edit' pk=ip.pk %}?return_url={{ device.get_absolute_url }}" class="btn btn-info btn-xs" title="Edit interface">
|
||||||
|
<i class="glyphicon glyphicon-pencil" aria-hidden="true"></i>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
{% if perms.ipam.delete_ipaddress %}
|
{% if perms.ipam.delete_ipaddress %}
|
||||||
<a href="{% url 'ipam:ipaddress_delete' pk=ip.pk %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
|
<a href="{% url 'ipam:ipaddress_delete' pk=ip.pk %}?return_url={{ device.get_absolute_url }}" class="btn btn-danger btn-xs">
|
||||||
<i class="glyphicon glyphicon-trash" aria-hidden="true" title="Delete IP address"></i>
|
<i class="glyphicon glyphicon-trash" aria-hidden="true" title="Delete IP address"></i>
|
||||||
|
@ -9,6 +9,9 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block form %}
|
{% block form %}
|
||||||
|
{% for field in form.hidden_fields %}
|
||||||
|
{{ field }}
|
||||||
|
{% endfor %}
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><strong>IP Address</strong></div>
|
<div class="panel-heading"><strong>IP Address</strong></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
@ -33,18 +36,9 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
|
||||||
<label class="col-md-3 control-label">Interface</label>
|
|
||||||
<div class="col-md-9">
|
|
||||||
<p class="form-control-static">
|
|
||||||
{% if obj.interface %}
|
{% if obj.interface %}
|
||||||
{{ obj.interface }}
|
{% render_field form.interface %}
|
||||||
{% else %}
|
|
||||||
<span class="text-muted">None</span>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% render_field form.description %}
|
{% render_field form.description %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -207,6 +207,11 @@ class ObjectEditView(View):
|
|||||||
|
|
||||||
if '_addanother' in request.POST:
|
if '_addanother' in request.POST:
|
||||||
return redirect(request.path)
|
return redirect(request.path)
|
||||||
|
|
||||||
|
return_url = form.cleaned_data['return_url']
|
||||||
|
if return_url and is_safe_url(url=return_url, host=request.get_host()):
|
||||||
|
return redirect(return_url)
|
||||||
|
else:
|
||||||
return redirect(self.get_return_url(obj))
|
return redirect(self.get_return_url(obj))
|
||||||
|
|
||||||
return render(request, self.template_name, {
|
return render(request, self.template_name, {
|
||||||
|
Loading…
Reference in New Issue
Block a user