Skip to content

Commit

Permalink
Merge branch 'main' into 18433-fix-macaddress-primary-for-interface
Browse files Browse the repository at this point in the history
  • Loading branch information
DanSheps authored Jan 27, 2025
2 parents 3219609 + 57fa1dd commit ee5d7cf
Show file tree
Hide file tree
Showing 22 changed files with 175 additions and 121 deletions.
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/01-feature_request.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
name: ✨ Feature Request
type: Feature
description: Propose a new NetBox feature or enhancement
labels: ["type: feature", "status: needs triage"]
body:
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/02-bug_report.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
name: 🐛 Bug Report
type: Bug
description: Report a reproducible bug in the current release of NetBox
labels: ["type: bug", "status: needs triage"]
body:
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/03-documentation_change.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
name: 📖 Documentation Change
type: Documentation
description: Suggest an addition or modification to the NetBox documentation
labels: ["type: documentation", "status: needs triage"]
body:
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/04-translation.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
name: 🌍 Translation
type: Translation
description: Request support for a new language in the user interface
labels: ["type: translation"]
body:
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/05-housekeeping.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
name: 🏡 Housekeeping
type: Housekeeping
description: A change pertaining to the codebase itself (developers only)
labels: ["type: housekeeping"]
body:
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/06-deprecation.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
name: 🗑️ Deprecation
type: Deprecation
description: The removal of an existing feature or resource
labels: ["type: deprecation"]
body:
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@ name: CI
on:
push:
paths-ignore:
- '.github/ISSUE_TEMPLATE/**'
- '.github/PULL_REQUEST_TEMPLATE.md'
- 'contrib/**'
- 'docs/**'
- 'netbox/translations/**'
pull_request:
paths-ignore:
- '.github/ISSUE_TEMPLATE/**'
- '.github/PULL_REQUEST_TEMPLATE.md'
- 'contrib/**'
- 'docs/**'
- 'netbox/translations/**'
Expand Down
2 changes: 1 addition & 1 deletion docs/features/facilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Regions will always be listed alphabetically by name within each parent, and the

Like regions, site groups can be arranged in a recursive hierarchy for grouping sites. However, whereas regions are intended for geographic organization, site groups may be used for functional grouping. For example, you might classify sites as corporate, branch, or customer sites in addition to where they are physically located.

The use of both regions and site groups affords to independent but complementary dimensions across which sites can be organized.
The use of both regions and site groups affords two independent but complementary dimensions across which sites can be organized.

## Sites

Expand Down
3 changes: 3 additions & 0 deletions docs/installation/1-postgresql.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ GRANT CREATE ON SCHEMA public TO netbox;
!!! danger "Use a strong password"
**Do not use the password from the example.** Choose a strong, random password to ensure secure database authentication for your NetBox installation.

!!! danger "Use UTF8 encoding"
Make sure that your database uses `UTF8` encoding (the default for new installations). Especially do not use `SQL_ASCII` encoding, as it can lead to unpredictable and unrecoverable errors. Enter `\l` to check your encoding.

Once complete, enter `\q` to exit the PostgreSQL shell.

## Verify Service Status
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# Generated by Django 5.0.9 on 2024-10-21 17:34
import django.db.models.deletion
from django.db import migrations, models

Expand All @@ -16,7 +15,7 @@ def populate_denormalized_fields(apps, schema_editor):
termination._site_id = termination.site_id
# Note: Location cannot be set prior to migration

CircuitTermination.objects.bulk_update(terminations, ['_region', '_site_group', '_site'])
CircuitTermination.objects.bulk_update(terminations, ['_region', '_site_group', '_site'], batch_size=100)


class Migration(migrations.Migration):
Expand Down
8 changes: 4 additions & 4 deletions netbox/dcim/base_filtersets.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ class ScopedFilterSet(BaseFilterSet):
label=_('Site (slug)'),
)
location_id = TreeNodeMultipleChoiceFilter(
queryset=Location.objects.all(),
field_name='_location',
lookup_expr='in',
label=_('Location (ID)'),
queryset=Location.objects.all(),
field_name='_location',
lookup_expr='in',
label=_('Location (ID)'),
)
location = TreeNodeMultipleChoiceFilter(
queryset=Location.objects.all(),
Expand Down
4 changes: 2 additions & 2 deletions netbox/dcim/filtersets.py
Original file line number Diff line number Diff line change
Expand Up @@ -1652,8 +1652,8 @@ def search(self, queryset, name, value):
if not value.strip():
return queryset
qs_filter = (
Q(mac_address__icontains=value) |
Q(description__icontains=value)
Q(mac_address__icontains=value) |
Q(description__icontains=value)
)
return queryset.filter(qs_filter)

Expand Down
5 changes: 5 additions & 0 deletions netbox/dcim/forms/model_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -1810,6 +1810,11 @@ def __init__(self, *args, **kwargs):

super().__init__(*args, **kwargs)

if instance and instance.assigned_object and instance.assigned_object.primary_mac_address:
if instance.assigned_object.primary_mac_address.pk == instance.pk:
self.fields['interface'].disabled = True
self.fields['vminterface'].disabled = True

def clean(self):
super().clean()

Expand Down
25 changes: 25 additions & 0 deletions netbox/dcim/models/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _

from core.models import ObjectType
from dcim.choices import *
from dcim.constants import *
from dcim.fields import MACAddressField
Expand Down Expand Up @@ -1523,9 +1524,33 @@ class Meta:
def __str__(self):
return str(self.mac_address)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

# Denote the original assigned object (if any) for validation in clean()
self._original_assigned_object_id = self.__dict__.get('assigned_object_id')
self._original_assigned_object_type_id = self.__dict__.get('assigned_object_type_id')

@cached_property
def is_primary(self):
if self.assigned_object and hasattr(self.assigned_object, 'primary_mac_address'):
if self.assigned_object.primary_mac_address and self.assigned_object.primary_mac_address.pk == self.pk:
return True
return False

def clean(self, *args, **kwargs):
super().clean()
if self._original_assigned_object_id and self._original_assigned_object_type_id:
assigned_object = self.assigned_object
ct = ObjectType.objects.get_for_id(self._original_assigned_object_type_id)
original_assigned_object = ct.get_object_for_this_type(pk=self._original_assigned_object_id)

if original_assigned_object.primary_mac_address:
if not assigned_object:
raise ValidationError(
_("Cannot unassign MAC Address while it is designated as the primary MAC for an object")
)
elif original_assigned_object != assigned_object:
raise ValidationError(
_("Cannot reassign MAC Address while it is designated as the primary MAC for an object")
)
2 changes: 1 addition & 1 deletion netbox/dcim/tables/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ class Meta(DeviceComponentTable.Meta):
model = models.Interface
fields = (
'pk', 'id', 'name', 'module_bay', 'module', 'label', 'enabled', 'type', 'parent', 'bridge', 'lag',
'mgmt_only', 'mtu', 'mode', 'mac_address', 'wwn', 'rf_role', 'rf_channel', 'rf_channel_frequency',
'mgmt_only', 'mtu', 'mode', 'primary_mac_address', 'wwn', 'rf_role', 'rf_channel', 'rf_channel_frequency',
'rf_channel_width', 'tx_power', 'description', 'mark_connected', 'cable', 'cable_color', 'wireless_link',
'wireless_lans', 'link_peer', 'connection', 'tags', 'vdcs', 'vrf', 'l2vpn', 'tunnel', 'ip_addresses',
'fhrp_groups', 'untagged_vlan', 'tagged_vlans', 'qinq_svlan', 'actions',
Expand Down
4 changes: 2 additions & 2 deletions netbox/extras/tests/test_customfields.py
Original file line number Diff line number Diff line change
Expand Up @@ -660,8 +660,8 @@ def setUpTestData(cls):
CustomField(
type=CustomFieldTypeChoices.TYPE_BOOLEAN,
name='boolean_field',
default=False)
,
default=False
),
CustomField(
type=CustomFieldTypeChoices.TYPE_DATE,
name='date_field',
Expand Down
2 changes: 1 addition & 1 deletion netbox/ipam/migrations/0072_prefix_cached_relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def populate_denormalized_fields(apps, schema_editor):
prefix._site_id = prefix.site_id
# Note: Location cannot be set prior to migration

Prefix.objects.bulk_update(prefixes, ['_region', '_site_group', '_site'])
Prefix.objects.bulk_update(prefixes, ['_region', '_site_group', '_site'], batch_size=100)


class Migration(migrations.Migration):
Expand Down
4 changes: 2 additions & 2 deletions netbox/ipam/models/vlans.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,15 +361,15 @@ class VLANTranslationRule(NetBoxModel):
)
local_vid = models.PositiveSmallIntegerField(
verbose_name=_('Local VLAN ID'),
validators=(
validators=(
MinValueValidator(VLAN_VID_MIN),
MaxValueValidator(VLAN_VID_MAX)
),
help_text=_("Numeric VLAN ID (1-4094)")
)
remote_vid = models.PositiveSmallIntegerField(
verbose_name=_('Remote VLAN ID'),
validators=(
validators=(
MinValueValidator(VLAN_VID_MIN),
MaxValueValidator(VLAN_VID_MAX)
),
Expand Down
Loading

0 comments on commit ee5d7cf

Please sign in to comment.