Skip to content

Commit

Permalink
Merge pull request #1278 from digitalocean/develop
Browse files Browse the repository at this point in the history
Release v2.0.7
  • Loading branch information
jeremystretch committed Jun 15, 2017
2 parents 5c63a49 + 9930e27 commit 88239e0
Show file tree
Hide file tree
Showing 23 changed files with 389 additions and 142 deletions.
24 changes: 13 additions & 11 deletions docs/installation/netbox.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
# Installation

**Debian/Ubuntu**
**Ubuntu**

Python 3:

```no-highlight
# apt-get install -y python3 python3-dev python3-pip libxml2-dev libxslt1-dev libffi-dev graphviz libpq-dev libssl-dev zlib1g-dev
# update-alternatives --install /usr/bin/python python /usr/bin/python3 1
```

Python 2:
Expand All @@ -15,7 +14,7 @@ Python 2:
# apt-get install -y python2.7 python-dev python-pip libxml2-dev libxslt1-dev libffi-dev graphviz libpq-dev libssl-dev zlib1g-dev
```

**CentOS/RHEL**
**CentOS**

Python 3:

Expand Down Expand Up @@ -57,13 +56,13 @@ Create the base directory for the NetBox installation. For this guide, we'll use

If `git` is not already installed, install it:

**Debian/Ubuntu**
**Ubuntu**

```no-highlight
# apt-get install -y git
```

**CentOS/RHEL**
**CentOS**

```no-highlight
# yum install -y git
Expand Down Expand Up @@ -150,11 +149,14 @@ You may use the script located at `netbox/generate_secret_key.py` to generate a

# Run Database Migrations

Before NetBox can run, we need to install the database schema. This is done by running `./manage.py migrate` from the `netbox` directory (`/opt/netbox/netbox/` in our example):
!!! warning
The examples on the rest of this page call the `python` executable, which will be Python2 on most systems. Replace this with `python3` if you're running NetBox on Python3.

Before NetBox can run, we need to install the database schema. This is done by running `python manage.py migrate` from the `netbox` directory (`/opt/netbox/netbox/` in our example):

```no-highlight
# cd /opt/netbox/netbox/
# ./manage.py migrate
# python manage.py migrate
Operations to perform:
Apply all migrations: dcim, sessions, admin, ipam, utilities, auth, circuits, contenttypes, extras, secrets, users
Running migrations:
Expand All @@ -172,7 +174,7 @@ If this step results in a PostgreSQL authentication error, ensure that the usern
NetBox does not come with any predefined user accounts. You'll need to create a super user to be able to log into NetBox:

```no-highlight
# ./manage.py createsuperuser
# python manage.py createsuperuser
Username: admin
Email address: admin@example.com
Password:
Expand All @@ -183,7 +185,7 @@ Superuser created successfully.
# Collect Static Files

```no-highlight
# ./manage.py collectstatic --no-input
# python manage.py collectstatic --no-input
You have requested to collect static files at the destination
location as specified in your settings:
Expand All @@ -204,7 +206,7 @@ NetBox ships with some initial data to help you get started: RIR definitions, co
This step is optional. It's perfectly fine to start using NetBox without using this initial data if you'd rather create everything from scratch.

```no-highlight
# ./manage.py loaddata initial_data
# python manage.py loaddata initial_data
Installed 43 object(s) from 4 fixture(s)
```

Expand All @@ -213,7 +215,7 @@ Installed 43 object(s) from 4 fixture(s)
At this point, NetBox should be able to run. We can verify this by starting a development instance:

```no-highlight
# ./manage.py runserver 0.0.0.0:8000 --insecure
# python manage.py runserver 0.0.0.0:8000 --insecure
Performing system checks...
System check identified no issues (0 silenced).
Expand Down
7 changes: 5 additions & 2 deletions docs/installation/postgresql.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
NetBox requires a PostgreSQL database to store data. (Please note that MySQL is not supported, as NetBox leverages PostgreSQL's built-in [network address types](https://www.postgresql.org/docs/9.1/static/datatype-net-types.html).)

!!! note
The installation instructions provided here have been tested to work on Ubuntu 16.04 and CentOS 6.9. The particular commands needed to install dependencies on other distributions may vary significantly. Unfortunately, this is outside the control of the NetBox maintainers. Please consult your distribution's documentation for assistance with any errors.

# Installation

**Debian/Ubuntu**
**Ubuntu**

```no-highlight
# apt-get update
# apt-get install -y postgresql libpq-dev
```

**CentOS/RHEL**
**CentOS**

```no-highlight
# yum install -y postgresql postgresql-server postgresql-devel
Expand Down
2 changes: 1 addition & 1 deletion docs/installation/web-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
We'll set up a simple WSGI front end using [gunicorn](http://gunicorn.org/) for the purposes of this guide. For web servers, we provide example configurations for both [nginx](https://www.nginx.com/resources/wiki/) and [Apache](http://httpd.apache.org/docs/2.4). (You are of course free to use whichever combination of HTTP and WSGI services you'd like.) We'll also use [supervisord](http://supervisord.org/) to enable service persistence.

!!! info
Only Debian/Ubuntu instructions are provided here, but the installation process for CentOS/RHEL does not differ much. Please consult the documentation for those distributions for details.
For the sake of brevity, only Ubuntu 16.04 instructions are provided here, but this sort of web server and WSGI configuration is not unique to NetBox. Please consult your distribution's documentation for assistance if needed.

```no-highlight
# apt-get install -y gunicorn supervisor
Expand Down
2 changes: 1 addition & 1 deletion netbox/circuits/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ class CircuitTerminationForm(BootstrapMixin, ChainedFieldsMixin, forms.ModelForm
label='Interface',
widget=APISelect(
api_url='/api/dcim/interfaces/?device_id={{device}}&type=physical',
disabled_indicator='is_connected'
disabled_indicator='connection'
)
)

Expand Down
8 changes: 4 additions & 4 deletions netbox/circuits/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

# Providers
url(r'^providers/$', views.ProviderListView.as_view(), name='provider_list'),
url(r'^providers/add/$', views.ProviderEditView.as_view(), name='provider_add'),
url(r'^providers/add/$', views.ProviderCreateView.as_view(), name='provider_add'),
url(r'^providers/import/$', views.ProviderBulkImportView.as_view(), name='provider_import'),
url(r'^providers/edit/$', views.ProviderBulkEditView.as_view(), name='provider_bulk_edit'),
url(r'^providers/delete/$', views.ProviderBulkDeleteView.as_view(), name='provider_bulk_delete'),
Expand All @@ -20,13 +20,13 @@

# Circuit types
url(r'^circuit-types/$', views.CircuitTypeListView.as_view(), name='circuittype_list'),
url(r'^circuit-types/add/$', views.CircuitTypeEditView.as_view(), name='circuittype_add'),
url(r'^circuit-types/add/$', views.CircuitTypeCreateView.as_view(), name='circuittype_add'),
url(r'^circuit-types/delete/$', views.CircuitTypeBulkDeleteView.as_view(), name='circuittype_bulk_delete'),
url(r'^circuit-types/(?P<slug>[\w-]+)/edit/$', views.CircuitTypeEditView.as_view(), name='circuittype_edit'),

# Circuits
url(r'^circuits/$', views.CircuitListView.as_view(), name='circuit_list'),
url(r'^circuits/add/$', views.CircuitEditView.as_view(), name='circuit_add'),
url(r'^circuits/add/$', views.CircuitCreateView.as_view(), name='circuit_add'),
url(r'^circuits/import/$', views.CircuitBulkImportView.as_view(), name='circuit_import'),
url(r'^circuits/edit/$', views.CircuitBulkEditView.as_view(), name='circuit_bulk_edit'),
url(r'^circuits/delete/$', views.CircuitBulkDeleteView.as_view(), name='circuit_bulk_delete'),
Expand All @@ -36,7 +36,7 @@
url(r'^circuits/(?P<pk>\d+)/terminations/swap/$', views.circuit_terminations_swap, name='circuit_terminations_swap'),

# Circuit terminations
url(r'^circuits/(?P<circuit>\d+)/terminations/add/$', views.CircuitTerminationEditView.as_view(), name='circuittermination_add'),
url(r'^circuits/(?P<circuit>\d+)/terminations/add/$', views.CircuitTerminationCreateView.as_view(), name='circuittermination_add'),
url(r'^circuit-terminations/(?P<pk>\d+)/edit/$', views.CircuitTerminationEditView.as_view(), name='circuittermination_edit'),
url(r'^circuit-terminations/(?P<pk>\d+)/delete/$', views.CircuitTerminationDeleteView.as_view(), name='circuittermination_delete'),

Expand Down
32 changes: 24 additions & 8 deletions netbox/circuits/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,18 @@ def get(self, request, slug):
})


class ProviderEditView(PermissionRequiredMixin, ObjectEditView):
permission_required = 'circuits.change_provider'
class ProviderCreateView(PermissionRequiredMixin, ObjectEditView):
permission_required = 'circuits.add_provider'
model = Provider
form_class = forms.ProviderForm
template_name = 'circuits/provider_edit.html'
default_return_url = 'circuits:provider_list'


class ProviderEditView(ProviderCreateView):
permission_required = 'circuits.change_provider'


class ProviderDeleteView(PermissionRequiredMixin, ObjectDeleteView):
permission_required = 'circuits.delete_provider'
model = Provider
Expand Down Expand Up @@ -96,15 +100,19 @@ class CircuitTypeListView(ObjectListView):
template_name = 'circuits/circuittype_list.html'


class CircuitTypeEditView(PermissionRequiredMixin, ObjectEditView):
permission_required = 'circuits.change_circuittype'
class CircuitTypeCreateView(PermissionRequiredMixin, ObjectEditView):
permission_required = 'circuits.add_circuittype'
model = CircuitType
form_class = forms.CircuitTypeForm

def get_return_url(self, request, obj):
return reverse('circuits:circuittype_list')


class CircuitTypeEditView(CircuitTypeCreateView):
permission_required = 'circuits.change_circuittype'


class CircuitTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
permission_required = 'circuits.delete_circuittype'
cls = CircuitType
Expand Down Expand Up @@ -146,14 +154,18 @@ def get(self, request, pk):
})


class CircuitEditView(PermissionRequiredMixin, ObjectEditView):
permission_required = 'circuits.change_circuit'
class CircuitCreateView(PermissionRequiredMixin, ObjectEditView):
permission_required = 'circuits.add_circuit'
model = Circuit
form_class = forms.CircuitForm
template_name = 'circuits/circuit_edit.html'
default_return_url = 'circuits:circuit_list'


class CircuitEditView(CircuitCreateView):
permission_required = 'circuits.change_circuit'


class CircuitDeleteView(PermissionRequiredMixin, ObjectDeleteView):
permission_required = 'circuits.delete_circuit'
model = Circuit
Expand Down Expand Up @@ -232,8 +244,8 @@ def circuit_terminations_swap(request, pk):
# Circuit terminations
#

class CircuitTerminationEditView(PermissionRequiredMixin, ObjectEditView):
permission_required = 'circuits.change_circuittermination'
class CircuitTerminationCreateView(PermissionRequiredMixin, ObjectEditView):
permission_required = 'circuits.add_circuittermination'
model = CircuitTermination
form_class = forms.CircuitTerminationForm
template_name = 'circuits/circuittermination_edit.html'
Expand All @@ -247,6 +259,10 @@ def get_return_url(self, request, obj):
return obj.circuit.get_absolute_url()


class CircuitTerminationEditView(CircuitTerminationCreateView):
permission_required = 'circuits.change_circuittermination'


class CircuitTerminationDeleteView(PermissionRequiredMixin, ObjectDeleteView):
permission_required = 'circuits.delete_circuittermination'
model = CircuitTermination
23 changes: 18 additions & 5 deletions netbox/dcim/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
from tenancy.models import Tenant
from utilities.forms import (
APISelect, add_blank_choice, ArrayFieldSelectMultiple, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect,
ChainedFieldsMixin, ChainedModelChoiceField, CommentField, CSVChoiceField, ExpandableNameField, FilterChoiceField,
FlexibleModelChoiceField, Livesearch, SelectWithDisabled, SmallTextarea, SlugField,
ChainedFieldsMixin, ChainedModelChoiceField, CommentField, ConfirmationForm, CSVChoiceField, ExpandableNameField,
FilterChoiceField, FlexibleModelChoiceField, Livesearch, SelectWithDisabled, SmallTextarea, SlugField,
FilterTreeNodeMultipleChoiceField,
)
from .formfields import MACAddressFormField
Expand Down Expand Up @@ -1174,6 +1174,10 @@ class Meta:
}


class ConsoleServerPortBulkDisconnectForm(ConfirmationForm):
pk = forms.ModelMultipleChoiceField(queryset=ConsoleServerPort.objects.all(), widget=forms.MultipleHiddenInput)


#
# Power ports
#
Expand Down Expand Up @@ -1431,6 +1435,10 @@ class Meta:
}


class PowerOutletBulkDisconnectForm(ConfirmationForm):
pk = forms.ModelMultipleChoiceField(queryset=PowerOutlet.objects.all(), widget=forms.MultipleHiddenInput)


#
# Interfaces
#
Expand Down Expand Up @@ -1508,6 +1516,10 @@ def __init__(self, *args, **kwargs):
self.fields['lag'].choices = []


class InterfaceBulkDisconnectForm(ConfirmationForm):
pk = forms.ModelMultipleChoiceField(queryset=Interface.objects.all(), widget=forms.MultipleHiddenInput)


#
# Interface connections
#
Expand Down Expand Up @@ -1594,9 +1606,10 @@ def __init__(self, device_a, *args, **kwargs):
]

# Mark connected interfaces as disabled
self.fields['interface_b'].choices = [
(iface.id, {'label': iface.name, 'disabled': iface.is_connected}) for iface in self.fields['interface_b'].queryset
]
if self.data.get('device_b'):
self.fields['interface_b'].choices = [
(iface.id, {'label': iface.name, 'disabled': iface.is_connected}) for iface in self.fields['interface_b'].queryset
]


class InterfaceConnectionCSVForm(forms.ModelForm):
Expand Down
Loading

0 comments on commit 88239e0

Please sign in to comment.