Merged develop

This commit is contained in:
Jeremy Stretch 2016-08-22 15:49:41 -04:00
commit faed3c1314
23 changed files with 53 additions and 145 deletions

View File

@ -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

View File

@ -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 '',

View File

@ -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',

View File

@ -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);

View File

@ -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):

View File

@ -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">

View File

@ -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">

View File

@ -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 %}

View File

@ -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">

View File

@ -53,6 +53,11 @@
<td>Name of tenant (optional)</td>
<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>
@ -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 %}

View File

@ -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">

View File

@ -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>

View File

@ -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 %}

View File

@ -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' %}

View File

@ -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 %}

View File

@ -107,20 +107,10 @@
<span class="text-muted">N/A</span>
{% 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">

View File

@ -79,20 +79,10 @@
<span class="text-muted">N/A</span>
{% 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">

View File

@ -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 %}

View File

@ -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">

View File

@ -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">

View File

@ -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">

View File

@ -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>

View File

@ -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: