diff --git a/Dockerfile b/Dockerfile
index c2e2c38ab..2cf8b9294 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,24 +1,11 @@
-FROM ubuntu:14.04
+FROM python:2.7-wheezy
-RUN apt-get update && apt-get install -y \
- python2.7 \
- python-dev \
- git \
- python-pip \
- libxml2-dev \
- libxslt1-dev \
- libffi-dev \
- graphviz \
- libpq-dev \
- build-essential \
- gunicorn \
- --no-install-recommends \
- && rm -rf /var/lib/apt/lists/* \
- && mkdir -p /opt/netbox \
- && cd /opt/netbox \
- && git clone --depth 1 https://github.com/digitalocean/netbox.git -b master . \
- && pip install -r requirements.txt \
- && apt-get purge -y --auto-remove git build-essential
+WORKDIR /opt/netbox
+
+ARG BRANCH=master
+ARG URL=https://github.com/digitalocean/netbox.git
+RUN git clone --depth 1 $URL -b $BRANCH . && \
+ pip install gunicorn==17.5 && pip install -r requirements.txt
ADD docker/docker-entrypoint.sh /docker-entrypoint.sh
ADD netbox/netbox/configuration.docker.py /opt/netbox/netbox/netbox/configuration.py
diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py
index 7a64705a3..0b8b09049 100644
--- a/netbox/ipam/models.py
+++ b/netbox/ipam/models.py
@@ -280,6 +280,7 @@ class Prefix(CreatedUpdatedModel, CustomFieldModel):
return ','.join([
str(self.prefix),
self.vrf.rd if self.vrf else '',
+ self.tenant.name if self.tenant else '',
self.site.name if self.site else '',
self.get_status_display(),
self.role.name if self.role else '',
@@ -384,6 +385,7 @@ class IPAddress(CreatedUpdatedModel, CustomFieldModel):
return ','.join([
str(self.address),
self.vrf.rd if self.vrf else '',
+ self.tenant.name if self.tenant else '',
self.device.identifier if self.device else '',
self.interface.name if self.interface else '',
'True' if is_primary else '',
diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py
index 6e2359ebe..289367d37 100644
--- a/netbox/netbox/settings.py
+++ b/netbox/netbox/settings.py
@@ -164,6 +164,9 @@ STATICFILES_DIRS = (
os.path.join(BASE_DIR, "project-static"),
)
+# Disable default limit of 1000 fields per request. Needed for bulk deletion of objects. (Added in Django 1.10.)
+DATA_UPLOAD_MAX_NUMBER_FIELDS = None
+
# Messages
MESSAGE_TAGS = {
messages.ERROR: 'danger',
diff --git a/netbox/project-static/js/secrets.js b/netbox/project-static/js/secrets.js
index 7f67cdcda..fadcc0d39 100644
--- a/netbox/project-static/js/secrets.js
+++ b/netbox/project-static/js/secrets.js
@@ -25,17 +25,20 @@ $(document).ready(function() {
});
// Adding/editing a secret
- $('form.requires-private-key').submit(function(event) {
+ private_key_field = $('#id_private_key');
+ private_key_field.parents('form').submit(function(event) {
+ console.log("form submitted");
var private_key = sessionStorage.getItem('private_key');
if (private_key) {
- $('#id_private_key').val(private_key);
- } else {
+ private_key_field.val(private_key);
+ } else if ($('form .requires-private-key:first').val()) {
+ console.log("we need a key!");
$('#privkey_modal').modal('show');
return false;
}
});
- // Prompt the user to enter a private RSA key for decryption
+ // Saving a private RSA key locally
$('#submit_privkey').click(function() {
var private_key = $('#user_privkey').val();
sessionStorage.setItem('private_key', private_key);
diff --git a/netbox/secrets/forms.py b/netbox/secrets/forms.py
index 06c963957..1e45fe163 100644
--- a/netbox/secrets/forms.py
+++ b/netbox/secrets/forms.py
@@ -47,8 +47,9 @@ class SecretRoleForm(forms.ModelForm, BootstrapMixin):
#
class SecretForm(forms.ModelForm, BootstrapMixin):
- private_key = forms.CharField(widget=forms.HiddenInput())
- plaintext = forms.CharField(max_length=65535, required=False, label='Plaintext')
+ private_key = forms.CharField(required=False, widget=forms.HiddenInput())
+ plaintext = forms.CharField(max_length=65535, required=False, label='Plaintext',
+ widget=forms.TextInput(attrs={'class': 'requires-private-key'}))
plaintext2 = forms.CharField(max_length=65535, required=False, label='Plaintext (verify)')
class Meta:
@@ -56,7 +57,8 @@ class SecretForm(forms.ModelForm, BootstrapMixin):
fields = ['role', 'name', 'plaintext', 'plaintext2']
def clean(self):
- validate_rsa_key(self.cleaned_data['private_key'])
+ if self.cleaned_data['plaintext']:
+ validate_rsa_key(self.cleaned_data['private_key'])
def clean_plaintext2(self):
plaintext = self.cleaned_data['plaintext']
@@ -84,7 +86,7 @@ class SecretFromCSVForm(forms.ModelForm):
class SecretImportForm(BulkImportForm, BootstrapMixin):
private_key = forms.CharField(widget=forms.HiddenInput())
- csv = CSVDataField(csv_form=SecretFromCSVForm)
+ csv = CSVDataField(csv_form=SecretFromCSVForm, widget=forms.Textarea(attrs={'class': 'requires-private-key'}))
class SecretBulkEditForm(forms.Form, BootstrapMixin):
diff --git a/netbox/templates/circuits/circuit.html b/netbox/templates/circuits/circuit.html
index 346e248e8..8844dc43a 100644
--- a/netbox/templates/circuits/circuit.html
+++ b/netbox/templates/circuits/circuit.html
@@ -95,26 +95,16 @@
Commit Rate |
- {% if circuit.commit_speed %}
- {{ circuit.commit_speed_human }}
+ {% if circuit.commit_rate %}
+ {{ circuit.commit_rate_human }}
{% else %}
N/A
{% endif %}
|
-
- Created |
- {{ circuit.created }} |
-
-
- Last Updated |
- {{ circuit.last_updated }} |
-
- {% with circuit.custom_fields as custom_fields %}
- {% include 'inc/custom_fields_panel.html' %}
- {% endwith %}
+ {% include 'inc/created_updated.html' with obj=circuit %}
diff --git a/netbox/templates/circuits/provider.html b/netbox/templates/circuits/provider.html
index 99b82b410..742dbcc3e 100644
--- a/netbox/templates/circuits/provider.html
+++ b/netbox/templates/circuits/provider.html
@@ -103,14 +103,6 @@
{% endif %}
-
- Created |
- {{ provider.created }} |
-
-
- Last Updated |
- {{ provider.last_updated }} |
-
{% with provider.custom_fields as custom_fields %}
@@ -128,6 +120,7 @@
{% endif %}
+ {% include 'inc/created_updated.html' with obj=provider %}
diff --git a/netbox/templates/dcim/device.html b/netbox/templates/dcim/device.html
index ffd08c415..754c9c2a8 100644
--- a/netbox/templates/dcim/device.html
+++ b/netbox/templates/dcim/device.html
@@ -79,14 +79,6 @@
{% endif %}
-
- Created |
- {{ device.created }} |
-
-
- Last Updated |
- {{ device.last_updated }} |
-
@@ -309,6 +301,7 @@
None found
{% endif %}
+ {% include 'inc/created_updated.html' with obj=device %}
{% if device_bays or device.device_type.is_parent_device %}
diff --git a/netbox/templates/dcim/rack.html b/netbox/templates/dcim/rack.html
index 9808e434f..11d7fb411 100644
--- a/netbox/templates/dcim/rack.html
+++ b/netbox/templates/dcim/rack.html
@@ -130,14 +130,6 @@
{{ rack.devices.count }}
-
- Created |
- {{ rack.created }} |
-
-
- Last Updated |
- {{ rack.last_updated }} |
-
{% with rack.custom_fields as custom_fields %}
@@ -190,6 +182,7 @@
{% endif %}
+ {% include 'inc/created_updated.html' with obj=rack %}
diff --git a/netbox/templates/dcim/rack_import.html b/netbox/templates/dcim/rack_import.html
index e088f0809..c5775cffd 100644
--- a/netbox/templates/dcim/rack_import.html
+++ b/netbox/templates/dcim/rack_import.html
@@ -53,6 +53,11 @@
Name of tenant (optional) |
Pied Piper |
+
+ Role |
+ Functional role (optional) |
+ Compute |
+
Type |
Rack type (optional) |
@@ -71,7 +76,7 @@
Example
- DC-4,Cage 1400,R101,J12.100,Pied Piper,4-post cabinet,19,42
+ DC-4,Cage 1400,R101,J12.100,Pied Piper,Compute,4-post cabinet,19,42
{% endblock %}
diff --git a/netbox/templates/dcim/site.html b/netbox/templates/dcim/site.html
index 539340965..ffcf382ab 100644
--- a/netbox/templates/dcim/site.html
+++ b/netbox/templates/dcim/site.html
@@ -109,14 +109,6 @@
{% endif %}
-
- Created |
- {{ site.created }} |
-
-
- Last Updated |
- {{ site.last_updated }} |
-
{% with site.custom_fields as custom_fields %}
@@ -134,6 +126,7 @@
{% endif %}
+ {% include 'inc/created_updated.html' with obj=site %}
diff --git a/netbox/templates/inc/created_updated.html b/netbox/templates/inc/created_updated.html
new file mode 100644
index 000000000..001bb6b85
--- /dev/null
+++ b/netbox/templates/inc/created_updated.html
@@ -0,0 +1,3 @@
+
+ Created {{ obj.created }} · Updated {{ obj.last_updated|timesince }} ago
+
diff --git a/netbox/templates/ipam/aggregate.html b/netbox/templates/ipam/aggregate.html
index 3c1eef905..e2b4086b1 100644
--- a/netbox/templates/ipam/aggregate.html
+++ b/netbox/templates/ipam/aggregate.html
@@ -77,16 +77,9 @@
{% endif %}
-
- Created |
- {{ aggregate.created }} |
-
-
- Last Updated |
- {{ aggregate.last_updated }} |
-
+ {% include 'inc/created_updated.html' with obj=aggregate %}
{% with aggregate.custom_fields as custom_fields %}
diff --git a/netbox/templates/ipam/ipaddress.html b/netbox/templates/ipam/ipaddress.html
index 00756b5ac..56f95479b 100644
--- a/netbox/templates/ipam/ipaddress.html
+++ b/netbox/templates/ipam/ipaddress.html
@@ -119,19 +119,9 @@
{% endif %}
-
- Created |
- {{ ipaddress.created }} |
-
-
- Last Updated |
- {{ ipaddress.last_updated }} |
-
- {% with ipaddress.custom_fields as custom_fields %}
- {% include 'inc/custom_fields_panel.html' %}
- {% endwith %}
+ {% include 'inc/created_updated.html' with obj=ipaddress %}
{% with heading='Parent Prefixes' %}
diff --git a/netbox/templates/ipam/prefix.html b/netbox/templates/ipam/prefix.html
index d49201bd1..24a40ed66 100644
--- a/netbox/templates/ipam/prefix.html
+++ b/netbox/templates/ipam/prefix.html
@@ -99,19 +99,10 @@
IP Addresses |
{{ ipaddress_count }} |
-
- Created |
- {{ prefix.created }} |
-
-
- Last Updated |
- {{ prefix.last_updated }} |
-
- {% with prefix.custom_fields as custom_fields %}
- {% include 'inc/custom_fields_panel.html' %}
- {% endwith %}
+ {% include 'inc/created_updated.html' with obj=prefix %}
+
{% if duplicate_prefix_table.rows %}
diff --git a/netbox/templates/ipam/vlan.html b/netbox/templates/ipam/vlan.html
index 27f713ba0..5b9d4cd3c 100644
--- a/netbox/templates/ipam/vlan.html
+++ b/netbox/templates/ipam/vlan.html
@@ -107,20 +107,10 @@
N/A
{% endif %}
-
-
- Created |
- {{ vlan.created }} |
-
-
- Last Updated |
- {{ vlan.last_updated }} |
- {% with vlan.custom_fields as custom_fields %}
- {% include 'inc/custom_fields_panel.html' %}
- {% endwith %}
+ {% include 'inc/created_updated.html' with obj=vlan %}
diff --git a/netbox/templates/ipam/vrf.html b/netbox/templates/ipam/vrf.html
index 3c89694e2..899b14f54 100644
--- a/netbox/templates/ipam/vrf.html
+++ b/netbox/templates/ipam/vrf.html
@@ -79,20 +79,10 @@
N/A
{% endif %}
-
-
- Created |
- {{ vrf.created }} |
-
-
- Last Updated |
- {{ vrf.last_updated }} |
- {% with vrf.custom_fields as custom_fields %}
- {% include 'inc/custom_fields_panel.html' %}
- {% endwith %}
+ {% include 'inc/created_updated.html' with obj=vrf %}
diff --git a/netbox/templates/secrets/secret.html b/netbox/templates/secrets/secret.html
index 53cdb4d7c..98007c2b9 100644
--- a/netbox/templates/secrets/secret.html
+++ b/netbox/templates/secrets/secret.html
@@ -56,16 +56,9 @@
{% endif %}
-
- Created |
- {{ secret.created }} |
-
-
- Last Updated |
- {{ secret.last_updated }} |
-
+ {% include 'inc/created_updated.html' with obj=secret %}
{% if secret|decryptable_by:request.user %}
diff --git a/netbox/templates/secrets/secret_edit.html b/netbox/templates/secrets/secret_edit.html
index 9a3df1a45..c2426391f 100644
--- a/netbox/templates/secrets/secret_edit.html
+++ b/netbox/templates/secrets/secret_edit.html
@@ -5,7 +5,7 @@
{% block title %}{% if secret.pk %}Editing {{ secret }}{% else %}Add a Secret{% endif %}{% endblock %}
{% block content %}
-
{% endif %}
-