Skip to content

Commit

Permalink
Merge pull request #3745 from netbox-community/develop
Browse files Browse the repository at this point in the history
Release v2.6.8
  • Loading branch information
jeremystretch authored Dec 10, 2019
2 parents 9f7313e + 6a26519 commit 425670f
Show file tree
Hide file tree
Showing 30 changed files with 158 additions and 55 deletions.
File renamed without changes.
7 changes: 0 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,6 @@ Please see [the documentation](http://netbox.readthedocs.io/en/stable/) for
instructions on installing NetBox. To upgrade NetBox, please download the [latest release](https://github.com/netbox-community/netbox/releases)
and run `upgrade.sh`.

## Alternative Installations

* [Docker container](https://github.com/netbox-community/netbox-docker) (via [@cimnine](https://github.com/cimnine))
* [Vagrant deployment](https://github.com/ryanmerolle/netbox-vagrant) (via [@ryanmerolle](https://github.com/ryanmerolle))
* [Ansible deployment](https://github.com/lae/ansible-role-netbox) (via [@lae](https://github.com/lae))
* [Kubernetes deployment](https://github.com/CENGN/netbox-kubernetes) (via [@CENGN](https://github.com/CENGN))

# Providing Feedback

Feature requests and bug reports must be submitted as GiHub issues. (Please be
Expand Down
2 changes: 1 addition & 1 deletion docs/additional-features/custom-scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ class NewBranchScript(Script):
class Meta:
name = "New Branch"
description = "Provision a new branch site"
fields = ['site_name', 'switch_count', 'switch_model']
field_order = ['site_name', 'switch_count', 'switch_model']
site_name = StringVar(
description="Name of the new site"
Expand Down
1 change: 0 additions & 1 deletion docs/installation/3-http-daemon.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ server {
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
}
}
```
Expand Down
22 changes: 22 additions & 0 deletions docs/release-notes/version-2.6.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
# v2.6.8 (2019-12-10)

## Enhancements

* [#3139](https://github.com/netbox-community/netbox/issues/3139) - Disable password change form for LDAP-authenticated users
* [#3457](https://github.com/netbox-community/netbox/issues/3457) - Display cable colors on device view
* [#3329](https://github.com/netbox-community/netbox/issues/3329) - Remove obsolete P3P policy header
* [#3663](https://github.com/netbox-community/netbox/issues/3663) - Add query filters for `created` and `last_updated` fields
* [#3722](https://github.com/netbox-community/netbox/issues/3722) - Allow the underscore character in IPAddress DNS names

## Bug Fixes

* [#3312](https://github.com/netbox-community/netbox/issues/3312) - Fix validation error when editing power cables in bulk
* [#3644](https://github.com/netbox-community/netbox/issues/3644) - Fix exception when connecting a cable to a RearPort with no corresponding FrontPort
* [#3669](https://github.com/netbox-community/netbox/issues/3669) - Include `weight` field in prefix/VLAN role form
* [#3674](https://github.com/netbox-community/netbox/issues/3674) - Include comments on PowerFeed view
* [#3679](https://github.com/netbox-community/netbox/issues/3679) - Fix link for assigned ipaddress in interface page
* [#3709](https://github.com/netbox-community/netbox/issues/3709) - Prevent exception when importing an invalid cable definition
* [#3720](https://github.com/netbox-community/netbox/issues/3720) - Correctly indicate power feed terminations on cable list
* [#3724](https://github.com/netbox-community/netbox/issues/3724) - Fix API filtering of interfaces by more than one device name
* [#3725](https://github.com/netbox-community/netbox/issues/3725) - Enforce client validation for minimum service port number

# v2.6.7 (2019-11-01)

## Enhancements
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pages:
- Change Logging: 'additional-features/change-logging.md'
- Context Data: 'additional-features/context-data.md'
- Custom Fields: 'additional-features/custom-fields.md'
- Custom Links: 'additional-features/custom-links.md'
- Custom Scripts: 'additional-features/custom-scripts.md'
- Export Templates: 'additional-features/export-templates.md'
- Graphs: 'additional-features/graphs.md'
Expand Down
6 changes: 3 additions & 3 deletions netbox/circuits/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
from django.db.models import Q

from dcim.models import Region, Site
from extras.filters import CustomFieldFilterSet
from extras.filters import CustomFieldFilterSet, CreatedUpdatedFilterSet
from tenancy.filtersets import TenancyFilterSet
from utilities.filters import NameSlugSearchFilterSet, NumericInFilter, TagFilter, TreeNodeMultipleChoiceFilter
from .constants import *
from .models import Circuit, CircuitTermination, CircuitType, Provider


class ProviderFilter(CustomFieldFilterSet):
class ProviderFilter(CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
Expand Down Expand Up @@ -54,7 +54,7 @@ class Meta:
fields = ['id', 'name', 'slug']


class CircuitFilter(CustomFieldFilterSet, TenancyFilterSet):
class CircuitFilter(CustomFieldFilterSet, TenancyFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
Expand Down
3 changes: 2 additions & 1 deletion netbox/dcim/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,8 @@

# Cable endpoint types
CABLE_TERMINATION_TYPES = [
'consoleport', 'consoleserverport', 'interface', 'poweroutlet', 'powerport', 'frontport', 'rearport', 'circuittermination',
'consoleport', 'consoleserverport', 'interface', 'poweroutlet', 'powerport', 'frontport', 'rearport',
'circuittermination', 'powerfeed',
]

# Cable types
Expand Down
24 changes: 13 additions & 11 deletions netbox/dcim/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
from django.contrib.auth.models import User
from django.db.models import Q

from extras.filters import CustomFieldFilterSet, LocalConfigContextFilter
from extras.filters import CustomFieldFilterSet, LocalConfigContextFilter, CreatedUpdatedFilterSet
from tenancy.filtersets import TenancyFilterSet
from tenancy.models import Tenant
from utilities.constants import COLOR_CHOICES
from utilities.filters import (
MultiValueMACAddressFilter, MultiValueNumberFilter, NameSlugSearchFilterSet, NumericInFilter, TagFilter,
TreeNodeMultipleChoiceFilter,
MultiValueCharFilter, MultiValueMACAddressFilter, MultiValueNumberFilter, NameSlugSearchFilterSet, NumericInFilter,
TagFilter, TreeNodeMultipleChoiceFilter,
)
from virtualization.models import Cluster
from .constants import *
Expand Down Expand Up @@ -38,7 +38,7 @@ class Meta:
fields = ['id', 'name', 'slug']


class SiteFilter(TenancyFilterSet, CustomFieldFilterSet):
class SiteFilter(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
Expand Down Expand Up @@ -116,7 +116,7 @@ class Meta:
fields = ['id', 'name', 'slug', 'color']


class RackFilter(TenancyFilterSet, CustomFieldFilterSet):
class RackFilter(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
Expand Down Expand Up @@ -251,7 +251,7 @@ class Meta:
fields = ['id', 'name', 'slug']


class DeviceTypeFilter(CustomFieldFilterSet):
class DeviceTypeFilter(CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
Expand Down Expand Up @@ -423,7 +423,7 @@ class Meta:
fields = ['id', 'name', 'slug', 'napalm_driver']


class DeviceFilter(LocalConfigContextFilter, TenancyFilterSet, CustomFieldFilterSet):
class DeviceFilter(LocalConfigContextFilter, TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
Expand Down Expand Up @@ -696,7 +696,7 @@ class InterfaceFilter(django_filters.FilterSet):
method='search',
label='Search',
)
device = django_filters.CharFilter(
device = MultiValueCharFilter(
method='filter_device',
field_name='name',
label='Device',
Expand Down Expand Up @@ -749,8 +749,10 @@ def search(self, queryset, name, value):

def filter_device(self, queryset, name, value):
try:
device = Device.objects.get(**{name: value})
vc_interface_ids = device.vc_interfaces.values_list('id', flat=True)
devices = Device.objects.filter(**{'{}__in'.format(name): value})
vc_interface_ids = []
for device in devices:
vc_interface_ids.extend(device.vc_interfaces.values_list('id', flat=True))
return queryset.filter(pk__in=vc_interface_ids)
except Device.DoesNotExist:
return queryset.none()
Expand Down Expand Up @@ -1096,7 +1098,7 @@ def search(self, queryset, name, value):
return queryset.filter(qs_filter)


class PowerFeedFilter(CustomFieldFilterSet):
class PowerFeedFilter(CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
Expand Down
4 changes: 2 additions & 2 deletions netbox/dcim/migrations/0066_cables.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@ class Migration(migrations.Migration):
('length', models.PositiveSmallIntegerField(blank=True, null=True)),
('length_unit', models.PositiveSmallIntegerField(blank=True, null=True)),
('_abs_length', models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True)),
('termination_a_type', models.ForeignKey(limit_choices_to={'model__in': ['consoleport', 'consoleserverport', 'interface', 'poweroutlet', 'powerport', 'frontport', 'rearport', 'circuittermination']}, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.ContentType')),
('termination_b_type', models.ForeignKey(limit_choices_to={'model__in': ['consoleport', 'consoleserverport', 'interface', 'poweroutlet', 'powerport', 'frontport', 'rearport', 'circuittermination']}, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.ContentType')),
('termination_a_type', models.ForeignKey(limit_choices_to={'model__in': ['consoleport', 'consoleserverport', 'interface', 'poweroutlet', 'powerport', 'frontport', 'rearport', 'circuittermination', 'powerfeed']}, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.ContentType')),
('termination_b_type', models.ForeignKey(limit_choices_to={'model__in': ['consoleport', 'consoleserverport', 'interface', 'poweroutlet', 'powerport', 'frontport', 'rearport', 'circuittermination', 'powerfeed']}, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='contenttypes.ContentType')),
],
),
migrations.AlterUniqueTogether(
Expand Down
10 changes: 10 additions & 0 deletions netbox/dcim/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ class CableTermination(models.Model):
object_id_field='termination_b_id'
)

is_path_endpoint = True

class Meta:
abstract = True

Expand Down Expand Up @@ -2444,6 +2446,8 @@ class FrontPort(CableTermination, ComponentModel):
validators=[MinValueValidator(1), MaxValueValidator(64)]
)

is_path_endpoint = False

objects = NaturalOrderingManager()
tags = TaggableManager(through=TaggedItem)

Expand Down Expand Up @@ -2506,6 +2510,8 @@ class RearPort(CableTermination, ComponentModel):
validators=[MinValueValidator(1), MaxValueValidator(64)]
)

is_path_endpoint = False

objects = NaturalOrderingManager()
tags = TaggableManager(through=TaggedItem)

Expand Down Expand Up @@ -2838,6 +2844,8 @@ def get_absolute_url(self):
def clean(self):

# Validate that termination A exists
if not hasattr(self, 'termination_a_type'):
raise ValidationError('Termination A type has not been specified')
try:
self.termination_a_type.model_class().objects.get(pk=self.termination_a_id)
except ObjectDoesNotExist:
Expand All @@ -2846,6 +2854,8 @@ def clean(self):
})

# Validate that termination B exists
if not hasattr(self, 'termination_b_type'):
raise ValidationError('Termination B type has not been specified')
try:
self.termination_b_type.model_class().objects.get(pk=self.termination_b_id)
except ObjectDoesNotExist:
Expand Down
2 changes: 1 addition & 1 deletion netbox/dcim/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def update_connected_endpoints(instance, **kwargs):

# Check if this Cable has formed a complete path. If so, update both endpoints.
endpoint_a, endpoint_b, path_status = instance.get_path_endpoints()
if endpoint_a is not None and endpoint_b is not None:
if getattr(endpoint_a, 'is_path_endpoint', False) and getattr(endpoint_b, 'is_path_endpoint', False):
endpoint_a.connected_endpoint = endpoint_b
endpoint_a.connection_status = path_status
endpoint_a.save()
Expand Down
8 changes: 5 additions & 3 deletions netbox/dcim/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,10 @@
CABLE_TERMINATION_PARENT = """
{% if value.device %}
<a href="{{ value.device.get_absolute_url }}">{{ value.device }}</a>
{% else %}
{% elif value.circuit %}
<a href="{{ value.circuit.get_absolute_url }}">{{ value.circuit }}</a>
{% elif value.power_panel %}
<a href="{{ value.power_panel.get_absolute_url }}">{{ value.power_panel }}</a>
{% endif %}
"""

Expand Down Expand Up @@ -718,7 +720,7 @@ class CableTable(BaseTable):
orderable=False,
verbose_name='Termination A'
)
termination_a = tables.Column(
termination_a = tables.LinkColumn(
accessor=Accessor('termination_a'),
orderable=False,
verbose_name=''
Expand All @@ -729,7 +731,7 @@ class CableTable(BaseTable):
orderable=False,
verbose_name='Termination B'
)
termination_b = tables.Column(
termination_b = tables.LinkColumn(
accessor=Accessor('termination_b'),
orderable=False,
verbose_name=''
Expand Down
2 changes: 1 addition & 1 deletion netbox/extras/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def get_view_name(self):
router.register(r'_choices', views.ExtrasFieldChoicesViewSet, basename='field-choice')

# Custom field choices
router.register(r'_custom_field_choices', views.CustomFieldChoicesViewSet, base_name='custom-field-choice')
router.register(r'_custom_field_choices', views.CustomFieldChoicesViewSet, basename='custom-field-choice')

# Graphs
router.register(r'graphs', views.GraphViewSet)
Expand Down
21 changes: 21 additions & 0 deletions netbox/extras/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,24 @@ def search(self, queryset, name, value):
Q(user_name__icontains=value) |
Q(object_repr__icontains=value)
)


class CreatedUpdatedFilterSet(django_filters.FilterSet):
created = django_filters.DateFilter()
created__gte = django_filters.DateFilter(
field_name='created',
lookup_expr='gte'
)
created__lte = django_filters.DateFilter(
field_name='created',
lookup_expr='lte'
)
last_updated = django_filters.DateTimeFilter()
last_updated__gte = django_filters.DateTimeFilter(
field_name='last_updated',
lookup_expr='gte'
)
last_updated__lte = django_filters.DateTimeFilter(
field_name='last_updated',
lookup_expr='lte'
)
14 changes: 7 additions & 7 deletions netbox/ipam/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
from netaddr.core import AddrFormatError

from dcim.models import Site, Device, Interface
from extras.filters import CustomFieldFilterSet
from extras.filters import CustomFieldFilterSet, CreatedUpdatedFilterSet
from tenancy.filtersets import TenancyFilterSet
from utilities.filters import NameSlugSearchFilterSet, NumericInFilter, TagFilter
from virtualization.models import VirtualMachine
from .constants import *
from .models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF


class VRFFilter(TenancyFilterSet, CustomFieldFilterSet):
class VRFFilter(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
Expand Down Expand Up @@ -49,7 +49,7 @@ class Meta:
fields = ['name', 'slug', 'is_private']


class AggregateFilter(CustomFieldFilterSet):
class AggregateFilter(CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
Expand Down Expand Up @@ -110,7 +110,7 @@ class Meta:
fields = ['id', 'name', 'slug']


class PrefixFilter(TenancyFilterSet, CustomFieldFilterSet):
class PrefixFilter(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
Expand Down Expand Up @@ -247,7 +247,7 @@ def filter_mask_length(self, queryset, name, value):
return queryset.filter(prefix__net_mask_length=value)


class IPAddressFilter(TenancyFilterSet, CustomFieldFilterSet):
class IPAddressFilter(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
Expand Down Expand Up @@ -384,7 +384,7 @@ class Meta:
fields = ['id', 'name', 'slug']


class VLANFilter(TenancyFilterSet, CustomFieldFilterSet):
class VLANFilter(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilterSet):
id__in = NumericInFilter(
field_name='id',
lookup_expr='in'
Expand Down Expand Up @@ -444,7 +444,7 @@ def search(self, queryset, name, value):
return queryset.filter(qs_filter)


class ServiceFilter(django_filters.FilterSet):
class ServiceFilter(CreatedUpdatedFilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
Expand Down
6 changes: 5 additions & 1 deletion netbox/ipam/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ class RoleForm(BootstrapMixin, forms.ModelForm):
class Meta:
model = Role
fields = [
'name', 'slug',
'name', 'slug', 'weight',
]


Expand Down Expand Up @@ -1250,6 +1250,10 @@ class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
#

class ServiceForm(BootstrapMixin, CustomFieldForm):
port = forms.IntegerField(
min_value=1,
max_value=65535
)
tags = TagField(
required=False
)
Expand Down
Loading

0 comments on commit 425670f

Please sign in to comment.