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 %} -
+ {% csrf_token %} {{ form.private_key }}
diff --git a/netbox/templates/secrets/secret_import.html b/netbox/templates/secrets/secret_import.html index 56e4194e4..9c7f67640 100644 --- a/netbox/templates/secrets/secret_import.html +++ b/netbox/templates/secrets/secret_import.html @@ -17,7 +17,7 @@
{% endif %} - + {% csrf_token %} {% render_form form %}
diff --git a/netbox/templates/tenancy/tenant.html b/netbox/templates/tenancy/tenant.html index 9cce543ec..6fe140e53 100644 --- a/netbox/templates/tenancy/tenant.html +++ b/netbox/templates/tenancy/tenant.html @@ -63,14 +63,6 @@ {% endif %} - - Created - {{ tenant.created }} - - - Last Updated - {{ tenant.last_updated }} -
{% with tenant.custom_fields as custom_fields %} @@ -88,6 +80,7 @@ {% endif %} + {% include 'inc/created_updated.html' with obj=tenant %}
diff --git a/netbox/templates/users/userkey.html b/netbox/templates/users/userkey.html index cbc748d17..6318377c6 100644 --- a/netbox/templates/users/userkey.html +++ b/netbox/templates/users/userkey.html @@ -31,6 +31,7 @@ Edit user key
+ {% include 'inc/created_updated.html' with obj=userkey %} {% else %}

You don't have a user key on file.

diff --git a/netbox/utilities/forms.py b/netbox/utilities/forms.py index f1c942fe6..4cbc1028b 100644 --- a/netbox/utilities/forms.py +++ b/netbox/utilities/forms.py @@ -130,11 +130,11 @@ class CSVDataField(forms.CharField): '"New York, NY",new-york-ny,Other stuff' => ['New York, NY', 'new-york-ny', 'Other stuff'] """ csv_form = None + widget = forms.Textarea def __init__(self, csv_form, *args, **kwargs): self.csv_form = csv_form self.columns = self.csv_form().fields.keys() - self.widget = forms.Textarea super(CSVDataField, self).__init__(*args, **kwargs) self.strip = False if not self.label: