mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Merge branch 'develop' into develop-2.6
This commit is contained in:
15
CHANGELOG.md
15
CHANGELOG.md
@ -12,7 +12,9 @@ the Config Context from being included in any results.
|
||||
|
||||
### Tag Permissions Changed
|
||||
|
||||
NetBox now makes use of its own `Tag` model instead of the vanilla model which ships with django-taggit. This new model lives in the `extras` app and thus any permissions that you may have configured using "Taggit | Tag" should be changed to now use "Extras | Tag."
|
||||
NetBox now makes use of its own `Tag` model instead of the vanilla model which ships with django-taggit. This new model
|
||||
lives in the `extras` app and thus any permissions that you may have configured using "Taggit | Tag" should be changed
|
||||
to now use "Extras | Tag."
|
||||
|
||||
## Enhancements
|
||||
|
||||
@ -23,22 +25,31 @@ NetBox now makes use of its own `Tag` model instead of the vanilla model which s
|
||||
|
||||
---
|
||||
|
||||
v2.5.7 (FUTURE)
|
||||
v2.5.7 (2019-02-21)
|
||||
|
||||
## Enhancements
|
||||
|
||||
* [#2357](https://github.com/digitalocean/netbox/issues/2357) - Enable filtering of devices by rack face
|
||||
* [#2638](https://github.com/digitalocean/netbox/issues/2638) - Add button to copy unlocked secret to clipboard
|
||||
* [#2870](https://github.com/digitalocean/netbox/issues/2870) - Add Markdown rendering for provider NOC/admin contact fields
|
||||
* [#2878](https://github.com/digitalocean/netbox/issues/2878) - Add cable types for OS1/OS2 singlemode fiber
|
||||
* [#2890](https://github.com/digitalocean/netbox/issues/2890) - Add port types for APC fiber
|
||||
* [#2898](https://github.com/digitalocean/netbox/issues/2898) - Enable filtering cables list by connection status
|
||||
* [#2903](https://github.com/digitalocean/netbox/issues/2903) - Clarify purpose of tags field on interface edit form
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
* [#2852](https://github.com/digitalocean/netbox/issues/2852) - Allow filtering devices by null rack position
|
||||
* [#2884](https://github.com/digitalocean/netbox/issues/2884) - Don't display connect button for wireless interfaces
|
||||
* [#2888](https://github.com/digitalocean/netbox/issues/2888) - Correct foreground color of device roles in rack elevations
|
||||
* [#2893](https://github.com/digitalocean/netbox/issues/2893) - Remove duplicate display of VRF RD on IP address view
|
||||
* [#2895](https://github.com/digitalocean/netbox/issues/2895) - Fix filtering of nullable character fields
|
||||
* [#2901](https://github.com/digitalocean/netbox/issues/2901) - Fix ordering regions by site count
|
||||
* [#2910](https://github.com/digitalocean/netbox/issues/2910) - Fix config context list and edit forms to use Select2 elements
|
||||
* [#2912](https://github.com/digitalocean/netbox/issues/2912) - Cable type in filter form should be blank by default
|
||||
* [#2913](https://github.com/digitalocean/netbox/issues/2913) - Fix assigned prefixes link on VRF view
|
||||
* [#2914](https://github.com/digitalocean/netbox/issues/2914) - Fix empty connected circuit link on device interfaces list
|
||||
* [#2915](https://github.com/digitalocean/netbox/issues/2915) - Fix bulk editing of pass-through ports
|
||||
|
||||
v2.5.6 (2019-02-13)
|
||||
|
||||
|
@ -128,4 +128,4 @@ Reports can be run on the CLI by invoking the management command:
|
||||
python3 manage.py runreport <module>
|
||||
```
|
||||
|
||||
One or more report modules may be specified.
|
||||
where ``<module>`` is the name of the python file in the ``reports`` directory without the ``.py`` extension. One or more report modules may be specified.
|
||||
|
@ -43,6 +43,12 @@ RACK_STATUS_CHOICES = [
|
||||
[RACK_STATUS_DEPRECATED, 'Deprecated'],
|
||||
]
|
||||
|
||||
# Device rack position
|
||||
DEVICE_POSITION_CHOICES = [
|
||||
# Rack.u_height is limited to 100
|
||||
(i, 'Unit {}'.format(i)) for i in range(1, 101)
|
||||
]
|
||||
|
||||
# Parent/child device roles
|
||||
SUBDEVICE_ROLE_PARENT = True
|
||||
SUBDEVICE_ROLE_CHILD = False
|
||||
@ -270,11 +276,14 @@ PORT_TYPE_8P8C = 1000
|
||||
PORT_TYPE_110_PUNCH = 1100
|
||||
PORT_TYPE_ST = 2000
|
||||
PORT_TYPE_SC = 2100
|
||||
PORT_TYPE_SC_APC = 2110
|
||||
PORT_TYPE_FC = 2200
|
||||
PORT_TYPE_LC = 2300
|
||||
PORT_TYPE_LC_APC = 2310
|
||||
PORT_TYPE_MTRJ = 2400
|
||||
PORT_TYPE_MPO = 2500
|
||||
PORT_TYPE_LSH = 2600
|
||||
PORT_TYPE_LSH_APC = 2610
|
||||
PORT_TYPE_CHOICES = [
|
||||
[
|
||||
'Copper',
|
||||
@ -288,10 +297,13 @@ PORT_TYPE_CHOICES = [
|
||||
[
|
||||
[PORT_TYPE_FC, 'FC'],
|
||||
[PORT_TYPE_LC, 'LC'],
|
||||
[PORT_TYPE_LC_APC, 'LC/APC'],
|
||||
[PORT_TYPE_LSH, 'LSH'],
|
||||
[PORT_TYPE_LSH_APC, 'LSH/APC'],
|
||||
[PORT_TYPE_MPO, 'MPO'],
|
||||
[PORT_TYPE_MTRJ, 'MTRJ'],
|
||||
[PORT_TYPE_SC, 'SC'],
|
||||
[PORT_TYPE_SC_APC, 'SC/APC'],
|
||||
[PORT_TYPE_ST, 'ST'],
|
||||
]
|
||||
]
|
||||
|
@ -543,6 +543,10 @@ class DeviceFilter(CustomFieldFilterSet):
|
||||
queryset=Rack.objects.all(),
|
||||
label='Rack (ID)',
|
||||
)
|
||||
position = django_filters.ChoiceFilter(
|
||||
choices=DEVICE_POSITION_CHOICES,
|
||||
null_label='Non-racked'
|
||||
)
|
||||
cluster_id = django_filters.ModelMultipleChoiceFilter(
|
||||
queryset=Cluster.objects.all(),
|
||||
label='VM cluster (ID)',
|
||||
@ -602,7 +606,7 @@ class DeviceFilter(CustomFieldFilterSet):
|
||||
|
||||
class Meta:
|
||||
model = Device
|
||||
fields = ['serial', 'position', 'face']
|
||||
fields = ['serial', 'face']
|
||||
|
||||
def search(self, queryset, name, value):
|
||||
if not value.strip():
|
||||
|
@ -2410,7 +2410,7 @@ class FrontPortCreateForm(ComponentForm):
|
||||
|
||||
class FrontPortBulkEditForm(BootstrapMixin, AddRemoveTagsForm, BulkEditForm):
|
||||
pk = forms.ModelMultipleChoiceField(
|
||||
queryset=Interface.objects.all(),
|
||||
queryset=FrontPort.objects.all(),
|
||||
widget=forms.MultipleHiddenInput()
|
||||
)
|
||||
type = forms.ChoiceField(
|
||||
@ -2484,7 +2484,7 @@ class RearPortCreateForm(ComponentForm):
|
||||
|
||||
class RearPortBulkEditForm(BootstrapMixin, AddRemoveTagsForm, BulkEditForm):
|
||||
pk = forms.ModelMultipleChoiceField(
|
||||
queryset=Interface.objects.all(),
|
||||
queryset=RearPort.objects.all(),
|
||||
widget=forms.MultipleHiddenInput()
|
||||
)
|
||||
type = forms.ChoiceField(
|
||||
@ -2801,10 +2801,15 @@ class CableFilterForm(BootstrapMixin, forms.Form):
|
||||
label='Search'
|
||||
)
|
||||
type = forms.MultipleChoiceField(
|
||||
choices=CABLE_TYPE_CHOICES,
|
||||
choices=add_blank_choice(CABLE_TYPE_CHOICES),
|
||||
required=False,
|
||||
widget=StaticSelect2()
|
||||
)
|
||||
status = forms.ChoiceField(
|
||||
required=False,
|
||||
choices=add_blank_choice(CONNECTION_STATUS_CHOICES),
|
||||
widget=StaticSelect2()
|
||||
)
|
||||
color = forms.CharField(
|
||||
max_length=6,
|
||||
required=False,
|
||||
|
@ -2644,6 +2644,9 @@ class Cable(ChangeLoggedModel):
|
||||
self.length_unit,
|
||||
)
|
||||
|
||||
def get_status_class(self):
|
||||
return 'success' if self.status else 'info'
|
||||
|
||||
def get_path_endpoints(self):
|
||||
"""
|
||||
Traverse both ends of a cable path and return its connected endpoints. Note that one or both endpoints may be
|
||||
|
@ -647,6 +647,9 @@ class CableTable(BaseTable):
|
||||
orderable=False,
|
||||
verbose_name=''
|
||||
)
|
||||
status = tables.TemplateColumn(
|
||||
template_code=STATUS_LABEL
|
||||
)
|
||||
length = tables.TemplateColumn(
|
||||
template_code=CABLE_LENGTH,
|
||||
order_by='_abs_length'
|
||||
|
@ -22,7 +22,7 @@ except ImportError:
|
||||
)
|
||||
|
||||
|
||||
VERSION = '2.5.7-dev'
|
||||
VERSION = '2.5.8-dev'
|
||||
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
7
netbox/project-static/clipboard-2.0.4.min.js
vendored
Executable file
7
netbox/project-static/clipboard-2.0.4.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
@ -1,4 +1,6 @@
|
||||
$(document).ready(function() {
|
||||
// Instantiate ClipboardJS on all copy buttons
|
||||
new ClipboardJS('button.copy-secret');
|
||||
|
||||
// Unlocking a secret
|
||||
$('button.unlock-secret').click(function(event) {
|
||||
@ -45,6 +47,7 @@ $(document).ready(function() {
|
||||
console.log("Secret retrieved successfully");
|
||||
$('#secret_' + secret_id).text(response.plaintext);
|
||||
$('button.unlock-secret[secret-id=' + secret_id + ']').hide();
|
||||
$('button.copy-secret[secret-id=' + secret_id + ']').show();
|
||||
$('button.lock-secret[secret-id=' + secret_id + ']').show();
|
||||
} else {
|
||||
console.log("Secret was not decrypted. Prompt user for private key.");
|
||||
@ -67,6 +70,7 @@ $(document).ready(function() {
|
||||
var secret_div = $('#secret_' + secret_id);
|
||||
secret_div.html('********');
|
||||
$('button.lock-secret[secret-id=' + secret_id + ']').hide();
|
||||
$('button.copy-secret[secret-id=' + secret_id + ']').hide();
|
||||
$('button.unlock-secret[secret-id=' + secret_id + ']').show();
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,7 @@
|
||||
<script src="{% static 'jquery-ui-1.12.1/jquery-ui.min.js' %}"></script>
|
||||
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
|
||||
<script src="{% static 'select2-4.0.5/js/select2.min.js' %}"></script>
|
||||
<script src="{% static 'clipboard-2.0.4.min.js' %}"></script>
|
||||
<script src="{% static 'js/forms.js' %}?v{{ settings.VERSION }}"></script>
|
||||
<script type="text/javascript">
|
||||
var netbox_api_path = "/{{ settings.BASE_PATH }}api/";
|
||||
|
@ -85,11 +85,11 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>NOC Contact</td>
|
||||
<td>{{ provider.noc_contact|linebreaksbr|placeholder }}</td>
|
||||
<td class="rendered-markdown">{{ provider.noc_contact|gfm|placeholder }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Admin Contact</td>
|
||||
<td>{{ provider.admin_contact|linebreaksbr|placeholder }}</td>
|
||||
<td class="rendered-markdown">{{ provider.admin_contact|gfm|placeholder }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Circuits</td>
|
||||
|
@ -96,7 +96,7 @@
|
||||
{{ peer_termination.connected_endpoint.device }}
|
||||
</a><br/>
|
||||
<small>via <i class="fa fa-fw fa-globe" title="Circuit"></i>
|
||||
<a href="{{ iface.connected_endpoint.circuit.get_absolure_url }}">
|
||||
<a href="{{ iface.connected_endpoint.circuit.get_absolute_url }}">
|
||||
{{ iface.connected_endpoint.circuit.provider }}
|
||||
{{ iface.connected_endpoint.circuit }}
|
||||
</a>
|
||||
|
@ -87,7 +87,7 @@
|
||||
<tr>
|
||||
<td>Prefixes</td>
|
||||
<td>
|
||||
<a href="{% url 'ipam:prefix_list' %}?vrf={{ vrf.rd }}">{{ prefix_count }}</a>
|
||||
<a href="{% url 'ipam:prefix_list' %}?vrf_id={{ vrf.pk }}">{{ prefix_count }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -8,6 +8,9 @@
|
||||
<button class="btn btn-xs btn-success unlock-secret" secret-id="{{ secret.pk }}">
|
||||
<i class="fa fa-lock"></i> Unlock
|
||||
</button>
|
||||
<button class="btn btn-xs btn-default copy-secret collapse" secret-id="{{ secret.pk }}" data-clipboard-target="#secret_{{ secret.pk }}">
|
||||
<i class="fa fa-copy"></i> Copy
|
||||
</button>
|
||||
<button class="btn btn-xs btn-danger lock-secret collapse" secret-id="{{ secret.pk }}">
|
||||
<i class="fa fa-unlock-alt"></i> Lock
|
||||
</button>
|
||||
|
@ -77,11 +77,14 @@
|
||||
</form>
|
||||
<div class="row">
|
||||
<div class="col-md-2">Secret</div>
|
||||
<div class="col-md-8" id="secret_{{ secret.pk }}">********</div>
|
||||
<div class="col-md-2 text-right">
|
||||
<div class="col-md-6" id="secret_{{ secret.pk }}">********</div>
|
||||
<div class="col-md-4 text-right">
|
||||
<button class="btn btn-xs btn-success unlock-secret" secret-id="{{ secret.pk }}">
|
||||
<i class="fa fa-lock"></i> Unlock
|
||||
</button>
|
||||
<button class="btn btn-xs btn-default copy-secret collapse" secret-id="{{ secret.pk }}" data-clipboard-target="#secret_{{ secret.pk }}">
|
||||
<i class="fa fa-copy"></i> Copy
|
||||
</button>
|
||||
<button class="btn btn-xs btn-danger lock-secret collapse" secret-id="{{ secret.pk }}">
|
||||
<i class="fa fa-unlock-alt"></i> Lock
|
||||
</button>
|
||||
|
@ -4,6 +4,14 @@
|
||||
|
||||
{% block content %}
|
||||
<h1>{% block title %}Editing {{ table.rows|length }} {{ obj_type_plural|bettertitle }}{% endblock %}</h1>
|
||||
{% if form.errors %}
|
||||
<div class="panel panel-danger">
|
||||
<div class="panel-heading"><strong>Errors</strong></div>
|
||||
<div class="panel-body">
|
||||
{{ form.errors }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<form action="" method="post" class="form form-horizontal">
|
||||
{% csrf_token %}
|
||||
{% if request.POST.return_url %}
|
||||
|
Reference in New Issue
Block a user