Browse Source

Merged develop

Jeremy Stretch 8 years ago
parent
commit
faed3c1314

+ 7 - 20
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

+ 2 - 0
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 '',

+ 3 - 0
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',

+ 7 - 4
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);

+ 6 - 4
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):

+ 3 - 13
netbox/templates/circuits/circuit.html

@@ -95,26 +95,16 @@
                 <tr>
                     <td>Commit Rate</td>
                     <td>
-                        {% if circuit.commit_speed %}
-                            {{ circuit.commit_speed_human }}
+                        {% if circuit.commit_rate %}
+                            {{ circuit.commit_rate_human }}
                         {% else %}
                             <span class="text-muted">N/A</span>
                         {% endif %}
                     </td>
                 </tr>
-                <tr>
-                    <td>Created</td>
-                    <td>{{ circuit.created }}</td>
-                </tr>
-                <tr>
-                    <td>Last Updated</td>
-                    <td>{{ circuit.last_updated }}</td>
-                </tr>
             </table>
         </div>
-        {% with circuit.custom_fields as custom_fields %}
-            {% include 'inc/custom_fields_panel.html' %}
-        {% endwith %}
+        {% include 'inc/created_updated.html' with obj=circuit %}
 	</div>
 	<div class="col-md-6">
         <div class="panel panel-default">

+ 1 - 8
netbox/templates/circuits/provider.html

@@ -103,14 +103,6 @@
                         {% endif %}
                     </td>
                 </tr>
-                <tr>
-                    <td>Created</td>
-                    <td>{{ provider.created }}</td>
-                </tr>
-                <tr>
-                    <td>Last Updated</td>
-                    <td>{{ provider.last_updated }}</td>
-                </tr>
             </table>
         </div>
         {% with provider.custom_fields as custom_fields %}
@@ -128,6 +120,7 @@
                 {% endif %}
             </div>
         </div>
+        {% include 'inc/created_updated.html' with obj=provider %}
 	</div>
 	<div class="col-md-6">
         <div class="panel panel-default">

+ 1 - 8
netbox/templates/dcim/device.html

@@ -79,14 +79,6 @@
                         {% endif %}
                     </td>
                 </tr>
-                <tr>
-                    <td>Created</td>
-                    <td>{{ device.created }}</td>
-                </tr>
-                <tr>
-                    <td>Last Updated</td>
-                    <td>{{ device.last_updated }}</td>
-                </tr>
             </table>
         </div>
         <div class="panel panel-default">
@@ -309,6 +301,7 @@
                 <div class="panel-body text-muted">None found</div>
             {% endif %}
         </div>
+        {% include 'inc/created_updated.html' with obj=device %}
 	</div>
 	<div class="col-md-6">
         {% if device_bays or device.device_type.is_parent_device %}

+ 1 - 8
netbox/templates/dcim/rack.html

@@ -130,14 +130,6 @@
                         <a href="{% url 'dcim:device_list' %}?rack_id={{ rack.id }}">{{ rack.devices.count }}</a>
                     </td>
                 </tr>
-                <tr>
-                    <td>Created</td>
-                    <td>{{ rack.created }}</td>
-                </tr>
-                <tr>
-                    <td>Last Updated</td>
-                    <td>{{ rack.last_updated }}</td>
-                </tr>
             </table>
         </div>
         {% with rack.custom_fields as custom_fields %}
@@ -190,6 +182,7 @@
                 {% endif %}
             </div>
         </div>
+        {% include 'inc/created_updated.html' with obj=rack %}
 	</div>
     <div class="row col-md-6">
        <div class="col-md-6 col-sm-6 col-xs-12">

+ 6 - 1
netbox/templates/dcim/rack_import.html

@@ -54,6 +54,11 @@
 					<td>Pied Piper</td>
 				</tr>
 				<tr>
+					<td>Role</td>
+					<td>Functional role (optional)</td>
+					<td>Compute</td>
+				</tr>
+				<tr>
 					<td>Type</td>
 					<td>Rack type (optional)</td>
 					<td>4-post cabinet</td>
@@ -71,7 +76,7 @@
 			</tbody>
 		</table>
 		<h4>Example</h4>
-		<pre>DC-4,Cage 1400,R101,J12.100,Pied Piper,4-post cabinet,19,42</pre>
+		<pre>DC-4,Cage 1400,R101,J12.100,Pied Piper,Compute,4-post cabinet,19,42</pre>
 	</div>
 </div>
 {% endblock %}

+ 1 - 8
netbox/templates/dcim/site.html

@@ -109,14 +109,6 @@
                         {% endif %}
                     </td>
                 </tr>
-                <tr>
-                    <td>Created</td>
-                    <td>{{ site.created }}</td>
-                </tr>
-                <tr>
-                    <td>Last Updated</td>
-                    <td>{{ site.last_updated }}</td>
-                </tr>
             </table>
         </div>
         {% with site.custom_fields as custom_fields %}
@@ -134,6 +126,7 @@
                 {% endif %}
             </div>
         </div>
+        {% include 'inc/created_updated.html' with obj=site %}
     </div>
     <div class="col-md-5">
         <div class="panel panel-default">

+ 3 - 0
netbox/templates/inc/created_updated.html

@@ -0,0 +1,3 @@
+<p>
+    <small class="text-muted">Created {{ obj.created }} &middot; Updated <span title="{{ obj.last_updated }}">{{ obj.last_updated|timesince }}</span> ago</small>
+</p>

+ 1 - 8
netbox/templates/ipam/aggregate.html

@@ -77,16 +77,9 @@
                         {% endif %}
                     </td>
                 </tr>
-                <tr>
-                    <td>Created</td>
-                    <td>{{ aggregate.created }}</td>
-                </tr>
-                <tr>
-                    <td>Last Updated</td>
-                    <td>{{ aggregate.last_updated }}</td>
-                </tr>
             </table>
         </div>
+        {% include 'inc/created_updated.html' with obj=aggregate %}
     </div>
     <div class="col-md-6">
         {% with aggregate.custom_fields as custom_fields %}

+ 1 - 11
netbox/templates/ipam/ipaddress.html

@@ -119,19 +119,9 @@
                         {% endif %}
                     </td>
                 </tr>
-                <tr>
-                    <td>Created</td>
-                    <td>{{ ipaddress.created }}</td>
-                </tr>
-                <tr>
-                    <td>Last Updated</td>
-                    <td>{{ ipaddress.last_updated }}</td>
-                </tr>
             </table>
         </div>
-        {% with ipaddress.custom_fields as custom_fields %}
-            {% include 'inc/custom_fields_panel.html' %}
-        {% endwith %}
+        {% include 'inc/created_updated.html' with obj=ipaddress %}
 	</div>
 	<div class="col-md-6">
         {% with heading='Parent Prefixes' %}

+ 2 - 11
netbox/templates/ipam/prefix.html

@@ -99,19 +99,10 @@
                     <td>IP Addresses</td>
                     <td><a href="{% url 'ipam:prefix_ipaddresses' pk=prefix.pk %}">{{ ipaddress_count }}</a></td>
                 </tr>
-                <tr>
-                    <td>Created</td>
-                    <td>{{ prefix.created }}</td>
-                </tr>
-                <tr>
-                    <td>Last Updated</td>
-                    <td>{{ prefix.last_updated }}</td>
-                </tr>
             </table>
         </div>
-        {% with prefix.custom_fields as custom_fields %}
-            {% include 'inc/custom_fields_panel.html' %}
-        {% endwith %}
+        {% include 'inc/created_updated.html' with obj=prefix %}
+        <br />
 	</div>
 	<div class="col-md-7">
         {% if duplicate_prefix_table.rows %}

+ 1 - 11
netbox/templates/ipam/vlan.html

@@ -108,19 +108,9 @@
                         {% endif %}
                     </td>
                 </tr>
-                <tr>
-                    <td>Created</td>
-                    <td>{{ vlan.created }}</td>
-                </tr>
-                <tr>
-                    <td>Last Updated</td>
-                    <td>{{ vlan.last_updated }}</td>
-                </tr>
 		    </table>
         </div>
-        {% with vlan.custom_fields as custom_fields %}
-            {% include 'inc/custom_fields_panel.html' %}
-        {% endwith %}
+        {% include 'inc/created_updated.html' with obj=vlan %}
 	</div>
 	<div class="col-md-6">
         <div class="panel panel-default">

+ 1 - 11
netbox/templates/ipam/vrf.html

@@ -80,19 +80,9 @@
                         {% endif %}
                     </td>
                 </tr>
-                <tr>
-                    <td>Created</td>
-                    <td>{{ vrf.created }}</td>
-                </tr>
-                <tr>
-                    <td>Last Updated</td>
-                    <td>{{ vrf.last_updated }}</td>
-                </tr>
 		    </table>
         </div>
-        {% with vrf.custom_fields as custom_fields %}
-            {% include 'inc/custom_fields_panel.html' %}
-        {% endwith %}
+        {% include 'inc/created_updated.html' with obj=vrf %}
 	</div>
 	<div class="col-md-6">
         <div class="panel panel-default">

+ 1 - 8
netbox/templates/secrets/secret.html

@@ -56,16 +56,9 @@
                         {% endif %}
                     </td>
                 </tr>
-                <tr>
-                    <td>Created</td>
-                    <td>{{ secret.created }}</td>
-                </tr>
-                <tr>
-                    <td>Last Updated</td>
-                    <td>{{ secret.last_updated }}</td>
-                </tr>
             </table>
         </div>
+        {% include 'inc/created_updated.html' with obj=secret %}
 	</div>
 	<div class="col-md-6">
         {% if secret|decryptable_by:request.user %}

+ 1 - 1
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 %}
-<form action="." method="post" class="form form-horizontal requires-private-key">
+<form action="." method="post" class="form form-horizontal">
     {% csrf_token %}
     {{ form.private_key }}
     <div class="row">

+ 1 - 1
netbox/templates/secrets/secret_import.html

@@ -17,7 +17,7 @@
                 </div>
             </div>
         {% endif %}
-		<form action="." method="post" class="form requires-private-key">
+		<form action="." method="post" class="form">
 		    {% csrf_token %}
 		    {% render_form form %}
 		    <div class="form-group">

+ 1 - 8
netbox/templates/tenancy/tenant.html

@@ -63,14 +63,6 @@
                         {% endif %}
                     </td>
                 </tr>
-                <tr>
-                    <td>Created</td>
-                    <td>{{ tenant.created }}</td>
-                </tr>
-                <tr>
-                    <td>Last Updated</td>
-                    <td>{{ tenant.last_updated }}</td>
-                </tr>
             </table>
         </div>
         {% with tenant.custom_fields as custom_fields %}
@@ -88,6 +80,7 @@
                 {% endif %}
             </div>
         </div>
+        {% include 'inc/created_updated.html' with obj=tenant %}
 	</div>
 	<div class="col-md-5">
         <div class="panel panel-default">

+ 1 - 0
netbox/templates/users/userkey.html

@@ -31,6 +31,7 @@
                     Edit user key
                 </a>
             </div>
+            {% include 'inc/created_updated.html' with obj=userkey %}
         {% else %}
             <p>You don't have a user key on file.</p>
             <p>

+ 1 - 1
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: