Skip to content

Commit

Permalink
Closes #2434: Show 'Create & Assign IP Address' Button when Creating …
Browse files Browse the repository at this point in the history
…Interfaces
  • Loading branch information
thatmattlove committed Apr 30, 2021
1 parent abd9ffd commit de56e2b
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
70 changes: 70 additions & 0 deletions netbox/dcim/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import logging
from copy import deepcopy
from collections import OrderedDict

from django.contrib import messages
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist
from django.core.paginator import EmptyPage, PageNotAnInteger
from django.db import transaction
from django.db.models import F, Prefetch
Expand Down Expand Up @@ -1908,6 +1911,73 @@ class InterfaceCreateView(generic.ComponentCreateView):
model_form = forms.InterfaceForm
template_name = 'dcim/device_component_add.html'

def post(self, request):
logger = logging.getLogger('netbox.dcim.views.InterfaceCreateView')
form = self.form(request.POST, initial=request.GET)

if form.is_valid():

new_components = []
data = deepcopy(request.POST)

names = form.cleaned_data['name_pattern']
labels = form.cleaned_data.get('label_pattern')
for i, name in enumerate(names):
label = labels[i] if labels else None
# Initialize the individual component form
data['name'] = name
data['label'] = label
if hasattr(form, 'get_iterative_data'):
data.update(form.get_iterative_data(i))
component_form = self.model_form(data)

if component_form.is_valid():
new_components.append(component_form)
else:
for field, errors in component_form.errors.as_data().items():
# Assign errors on the child form's name/label field to name_pattern/label_pattern on the parent form
if field == 'name':
field = 'name_pattern'
elif field == 'label':
field = 'label_pattern'
for e in errors:
form.add_error(field, '{}: {}'.format(name, ', '.join(e)))

if not form.errors:
try:
# Create the new components
new_objs = []
with transaction.atomic():
for component_form in new_components:
obj = component_form.save()
new_objs.append(obj)

# Enforce object-level permissions
if self.queryset.filter(pk__in=[obj.pk for obj in new_objs]).count() != len(new_objs):
raise ObjectDoesNotExist

messages.success(request, "Added {} {}".format(
len(new_components), self.queryset.model._meta.verbose_name_plural
))
if '_addanother' in request.POST:
return redirect(request.get_full_path())
elif '_assignip' in request.POST and len(new_objs) >= 1 and request.user.has_perm('ipam.add_ipaddress'):
first_obj = new_objs[0].pk
return redirect(f'/ipam/ip-addresses/add/?interface={first_obj}&return_url={self.get_return_url(request)}')
else:
return redirect(self.get_return_url(request))

except ObjectDoesNotExist:
msg = "Component creation failed due to object-level permissions violation"
logger.debug(msg)
form.add_error(None, msg)

return render(request, self.template_name, {
'component_type': self.queryset.model._meta.verbose_name,
'form': form,
'return_url': self.get_return_url(request),
})


class InterfaceEditView(generic.ObjectEditView):
queryset = Interface.objects.all()
Expand Down
5 changes: 5 additions & 0 deletions netbox/templates/dcim/device_component_add.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ <h4>{{ component_type|title }}</h4>
<div class="col-md-8 text-end">
{% block buttons %}
<a class="btn btn-outline-danger" href="{{ return_url }}">Cancel</a>
{% if perms.ipam.add_ipaddress %}
<button type="submit" name="_assignip" class="btn btn-outline-success">
Create & Assign IP Address
</button>
{% endif %}
<button type="submit" name="_addanother" class="btn btn-outline-primary">
Create & Add Another
</button>
Expand Down

0 comments on commit de56e2b

Please sign in to comment.