Skip to content

Commit

Permalink
Merge pull request #438 from digitalocean/develop
Browse files Browse the repository at this point in the history
Release v1.4.2
  • Loading branch information
jeremystretch authored Aug 6, 2016
2 parents 946a1b7 + e55acf8 commit 93fccd5
Show file tree
Hide file tree
Showing 14 changed files with 128 additions and 36 deletions.
25 changes: 25 additions & 0 deletions netbox/dcim/migrations/0013_add_interface_form_factors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.8 on 2016-08-06 20:24
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('dcim', '0012_site_rack_device_add_tenant'),
]

operations = [
migrations.AlterField(
model_name='interface',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[[b'Virtual interfaces', [[0, b'Virtual']]], [b'Ethernet', [[800, b'100BASE-TX (10/100M)'], [1000, b'1000BASE-T (1GE)'], [1150, b'10GBASE-T (10GE)']]], [b'Modular', [[1050, b'GBIC (1GE)'], [1100, b'SFP (1GE)'], [1300, b'XFP (10GE)'], [1200, b'SFP+ (10GE)'], [1400, b'QSFP+ (40GE)'], [1500, b'CFP (100GE)'], [1600, b'QSFP28 (100GE)']]], [b'Serial', [[4000, b'T1 (1.544 Mbps)'], [4010, b'E1 (2.048 Mbps)'], [4040, b'T3 (45 Mbps)'], [4050, b'E3 (34 Mbps)']]], [b'Stacking', [[5000, b'Cisco StackWise'], [5050, b'Cisco StackWise Plus']]]], default=1200),
),
migrations.AlterField(
model_name='interfacetemplate',
name='form_factor',
field=models.PositiveSmallIntegerField(choices=[[b'Virtual interfaces', [[0, b'Virtual']]], [b'Ethernet', [[800, b'100BASE-TX (10/100M)'], [1000, b'1000BASE-T (1GE)'], [1150, b'10GBASE-T (10GE)']]], [b'Modular', [[1050, b'GBIC (1GE)'], [1100, b'SFP (1GE)'], [1300, b'XFP (10GE)'], [1200, b'SFP+ (10GE)'], [1400, b'QSFP+ (40GE)'], [1500, b'CFP (100GE)'], [1600, b'QSFP28 (100GE)']]], [b'Serial', [[4000, b'T1 (1.544 Mbps)'], [4010, b'E1 (2.048 Mbps)'], [4040, b'T3 (45 Mbps)'], [4050, b'E3 (34 Mbps)']]], [b'Stacking', [[5000, b'Cisco StackWise'], [5050, b'Cisco StackWise Plus']]]], default=1200),
),
]
59 changes: 51 additions & 8 deletions netbox/dcim/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,63 @@
IFACE_FF_VIRTUAL = 0
IFACE_FF_100M_COPPER = 800
IFACE_FF_1GE_COPPER = 1000
IFACE_FF_GBIC = 1050
IFACE_FF_SFP = 1100
IFACE_FF_10GE_COPPER = 1150
IFACE_FF_SFP_PLUS = 1200
IFACE_FF_XFP = 1300
IFACE_FF_QSFP_PLUS = 1400
IFACE_FF_CFP = 1500
IFACE_FF_QSFP28 = 1600
IFACE_FF_T1 = 4000
IFACE_FF_E1 = 4010
IFACE_FF_T3 = 4040
IFACE_FF_E3 = 4050
IFACE_FF_STACKWISE = 5000
IFACE_FF_STACKWISE_PLUS = 5050
IFACE_FF_CHOICES = [
[IFACE_FF_VIRTUAL, 'Virtual'],
[IFACE_FF_100M_COPPER, '10/100M (100BASE-TX)'],
[IFACE_FF_1GE_COPPER, '1GE (1000BASE-T)'],
[IFACE_FF_SFP, '1GE (SFP)'],
[IFACE_FF_10GE_COPPER, '10GE (10GBASE-T)'],
[IFACE_FF_SFP_PLUS, '10GE (SFP+)'],
[IFACE_FF_XFP, '10GE (XFP)'],
[IFACE_FF_QSFP_PLUS, '40GE (QSFP+)'],
[
'Virtual interfaces',
[
[IFACE_FF_VIRTUAL, 'Virtual'],
]
],
[
'Ethernet',
[
[IFACE_FF_100M_COPPER, '100BASE-TX (10/100M)'],
[IFACE_FF_1GE_COPPER, '1000BASE-T (1GE)'],
[IFACE_FF_10GE_COPPER, '10GBASE-T (10GE)'],
]
],
[
'Modular',
[
[IFACE_FF_GBIC, 'GBIC (1GE)'],
[IFACE_FF_SFP, 'SFP (1GE)'],
[IFACE_FF_XFP, 'XFP (10GE)'],
[IFACE_FF_SFP_PLUS, 'SFP+ (10GE)'],
[IFACE_FF_QSFP_PLUS, 'QSFP+ (40GE)'],
[IFACE_FF_CFP, 'CFP (100GE)'],
[IFACE_FF_QSFP28, 'QSFP28 (100GE)'],
]
],
[
'Serial',
[
[IFACE_FF_T1, 'T1 (1.544 Mbps)'],
[IFACE_FF_E1, 'E1 (2.048 Mbps)'],
[IFACE_FF_T3, 'T3 (45 Mbps)'],
[IFACE_FF_E3, 'E3 (34 Mbps)'],
]
],
[
'Stacking',
[
[IFACE_FF_STACKWISE, 'Cisco StackWise'],
[IFACE_FF_STACKWISE_PLUS, 'Cisco StackWise Plus'],
]
],
]

STATUS_ACTIVE = True
Expand Down
6 changes: 6 additions & 0 deletions netbox/extras/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,9 @@ class TopologyMapAdmin(admin.ModelAdmin):
prepopulated_fields = {
'slug': ['name'],
}


@admin.register(UserAction)
class UserActionAdmin(admin.ModelAdmin):
actions = None
list_display = ['user', 'action', 'content_type', 'object_id', 'message']
14 changes: 14 additions & 0 deletions netbox/ipam/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ class IPAddressFilter(django_filters.FilterSet):
action='search',
label='Search',
)
parent = django_filters.MethodFilter(
action='search_by_parent',
label='Parent prefix',
)
vrf = django_filters.MethodFilter(
action='_vrf',
label='VRF',
Expand Down Expand Up @@ -238,6 +242,16 @@ def search(self, queryset, value):
pass
return queryset.filter(qs_filter)

def search_by_parent(self, queryset, value):
value = value.strip()
if not value:
return queryset
try:
query = str(IPNetwork(value).cidr)
return queryset.filter(address__net_contained_or_equal=query)
except AddrFormatError:
return queryset.none()

def _vrf(self, queryset, value):
if str(value) == '':
return queryset
Expand Down
7 changes: 6 additions & 1 deletion netbox/ipam/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,9 @@ def prefix_role_choices():


class PrefixFilterForm(forms.Form, BootstrapMixin):
parent = forms.CharField(required=False, label='Search Within')
parent = forms.CharField(required=False, label='Search Within', widget=forms.TextInput(attrs={
'placeholder': 'Network',
}))
vrf = forms.MultipleChoiceField(required=False, choices=prefix_vrf_choices, label='VRF',
widget=forms.SelectMultiple(attrs={'size': 6}))
tenant = forms.MultipleChoiceField(required=False, choices=tenant_choices, label='Tenant',
Expand Down Expand Up @@ -444,6 +446,9 @@ def ipaddress_vrf_choices():


class IPAddressFilterForm(forms.Form, BootstrapMixin):
parent = forms.CharField(required=False, label='Search Within', widget=forms.TextInput(attrs={
'placeholder': 'Prefix',
}))
family = forms.ChoiceField(required=False, choices=ipaddress_family_choices, label='Address Family')
vrf = forms.MultipleChoiceField(required=False, choices=ipaddress_vrf_choices, label='VRF',
widget=forms.SelectMultiple(attrs={'size': 6}))
Expand Down
8 changes: 4 additions & 4 deletions netbox/ipam/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ def add_available_ipaddresses(prefix, ipaddress_list):
# Iterate through existing IPs and annotate free ranges
for ip in ipaddress_list:
if prev_ip:
skipped_count = int(ip.address.ip - prev_ip.address.ip - 1)
if skipped_count:
diff = int(ip.address.ip - prev_ip.address.ip)
if diff > 1:
first_skipped = '{}/{}'.format(prev_ip.address.ip + 1, prefix.prefixlen)
output.append((skipped_count, first_skipped))
output.append((diff - 1, first_skipped))
output.append(ip)
prev_ip = ip

Expand Down Expand Up @@ -373,7 +373,7 @@ class PrefixEditView(PermissionRequiredMixin, ObjectEditView):
permission_required = 'ipam.change_prefix'
model = Prefix
form_class = forms.PrefixForm
fields_initial = ['site', 'vrf', 'prefix']
fields_initial = ['vrf', 'tenant', 'site', 'prefix', 'vlan']
cancel_url = 'ipam:prefix_list'


Expand Down
2 changes: 1 addition & 1 deletion netbox/netbox/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"the documentation.")


VERSION = '1.4.1'
VERSION = '1.4.2'

# Import local configuration
for setting in ['ALLOWED_HOSTS', 'DATABASE', 'SECRET_KEY']:
Expand Down
2 changes: 1 addition & 1 deletion netbox/netbox/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def home(request):

return render(request, 'home.html', {
'stats': stats,
'recent_activity': UserAction.objects.select_related('user')[:15]
'recent_activity': UserAction.objects.select_related('user')[:50]
})


Expand Down
10 changes: 5 additions & 5 deletions netbox/project-static/js/forms.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ $(document).ready(function() {

// Slugify
function slugify(s, num_chars) {
s = s.replace(/[^\-\.\w\s]/g, ''); // Remove unneeded chars
s = s.replace(/^\s+|\s+$/g, ''); // Trim leading/trailing spaces
s = s.replace(/[\-\.\s]+/g, '-'); // Convert spaces and decimals to hyphens
s = s.toLowerCase(); // Convert to lowercase
return s.substring(0, num_chars); // Trim to first num_chars chars
s = s.replace(/[^\-\.\w\s]/g, ''); // Remove unneeded chars
s = s.replace(/^[\s\.]+|[\s\.]+$/g, ''); // Trim leading/trailing spaces
s = s.replace(/[\-\.\s]+/g, '-'); // Convert spaces and decimals to hyphens
s = s.toLowerCase(); // Convert to lowercase
return s.substring(0, num_chars); // Trim to first num_chars chars
}
var slug_field = $('#id_slug');
slug_field.change(function() {
Expand Down
4 changes: 2 additions & 2 deletions netbox/project-static/js/secrets.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ $(document).ready(function() {
},
success: function (response, status) {
$('#secret_' + secret_id).html(response.plaintext);
$('button.unlock-secret').hide();
$('button.lock-secret').show();
$('button.unlock-secret[secret-id=' + secret_id + ']').hide();
$('button.lock-secret[secret-id=' + secret_id + ']').show();
},
error: function (xhr, ajaxOptions, thrownError) {
if (xhr.status == 403) {
Expand Down
2 changes: 1 addition & 1 deletion netbox/secrets/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def secret_add(request, pk):

messages.success(request, "Added new secret: {0}".format(secret))
if '_addanother' in request.POST:
return redirect('secrets:secret_add')
return redirect('dcim:device_addsecret', pk=device.pk)
else:
return redirect('secrets:secret', pk=secret.pk)

Expand Down
8 changes: 8 additions & 0 deletions netbox/templates/ipam/vlan.html
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,14 @@ <h1>VLAN {{ vlan.display_name }}</h1>
<strong>Prefixes</strong>
</div>
{% render_table prefix_table %}
{% if perms.ipam.add_prefix %}
<div class="panel-footer text-right">
<a href="{% url 'ipam:prefix_add' %}?{% if vlan.tenant %}tenant={{ vlan.tenant.pk }}&{% endif %}site={{ vlan.site.pk }}&vlan={{ vlan.pk }}" class="btn btn-primary btn-xs">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
Add a prefix
</a>
</div>
{% endif %}
</div>
</div>
</div>
Expand Down
14 changes: 2 additions & 12 deletions netbox/templates/secrets/secret_edit.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,15 @@
{% load static from staticfiles %}
{% load form_helpers %}

{% block title %}{% if secret.pk %}Editing Secret: {{ secret }}{% else %}Add a Secret{% endif %}{% endblock %}
{% block title %}{% if secret.pk %}Editing {{ secret }}{% else %}Add a Secret{% endif %}{% endblock %}

{% block content %}
{% if secret.pk %}
<h1>Editing Secret: {{ secret }}</h1>
{% else %}
<h1>Add a Secret</h1>
{% endif %}
<form action="." method="post" class="form form-horizontal requires-private-key">
{% csrf_token %}
{{ form.private_key }}
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h3>{% if secret.pk %}Editing {{ secret }}{% else %}Add a Secret{% endif %}</h3>
{% if form.non_field_errors %}
<div class="panel panel-danger">
<div class="panel-heading"><strong>Errors</strong></div>
Expand All @@ -23,10 +19,6 @@ <h1>Add a Secret</h1>
</div>
</div>
{% endif %}
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading"><strong>Secret Attributes</strong></div>
<div class="panel-body">
Expand All @@ -41,8 +33,6 @@ <h1>Add a Secret</h1>
{% render_field form.userkeys %}
</div>
</div>
</div>
<div class="col-md-6">
<div class="panel panel-default">
<div class="panel-heading"><strong>Secret Data</strong></div>
<div class="panel-body">
Expand Down
3 changes: 2 additions & 1 deletion netbox/utilities/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,8 @@ def __init__(self, *args, **kwargs):
field.widget.attrs['class'] = 'form-control'
if field.required:
field.widget.attrs['required'] = 'required'
field.widget.attrs['placeholder'] = field.label
if 'placeholder' not in field.widget.attrs:
field.widget.attrs['placeholder'] = field.label


class ConfirmationForm(forms.Form, BootstrapMixin):
Expand Down

0 comments on commit 93fccd5

Please sign in to comment.