mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Add mark_utilized to IPRange
This commit is contained in:
committed by
Jeremy Stretch
parent
8a08d3621b
commit
536b46158a
@ -28,3 +28,7 @@ The IP range's operational status. Note that the status of a range does _not_ ha
|
||||
|
||||
!!! tip
|
||||
Additional statuses may be defined by setting `IPRange.status` under the [`FIELD_CHOICES`](../../configuration/data-validation.md#field_choices) configuration parameter.
|
||||
|
||||
### Mark Utilized
|
||||
|
||||
If enabled, the IP range will be considered 100% utilized regardless of how many IP addresses are defined within it. This is useful for documenting DHCP ranges, for example.
|
||||
|
@ -26,6 +26,7 @@ A new ASN range model has been introduced to facilitate the provisioning of new
|
||||
|
||||
### Enhancements
|
||||
|
||||
* [#7947](https://github.com/netbox-community/netbox/issues/7947) - Enable marking IP ranges as fully utilized
|
||||
* [#9073](https://github.com/netbox-community/netbox/issues/9073) - Enable syncing config context data from remote sources
|
||||
* [#9653](https://github.com/netbox-community/netbox/issues/9653) - Enable setting a default platform for device types
|
||||
* [#10374](https://github.com/netbox-community/netbox/issues/10374) - Require unique tenant names & slugs per group (not globally)
|
||||
|
@ -377,7 +377,7 @@ class IPRangeSerializer(NetBoxModelSerializer):
|
||||
model = IPRange
|
||||
fields = [
|
||||
'id', 'url', 'display', 'family', 'start_address', 'end_address', 'size', 'vrf', 'tenant', 'status', 'role',
|
||||
'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'children',
|
||||
'mark_utilized', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'children',
|
||||
]
|
||||
read_only_fields = ['family']
|
||||
|
||||
|
@ -468,7 +468,7 @@ class IPRangeFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
|
||||
|
||||
class Meta:
|
||||
model = IPRange
|
||||
fields = ['id', 'description']
|
||||
fields = ['id', 'mark_utilized', 'description']
|
||||
|
||||
def search(self, queryset, name, value):
|
||||
if not value.strip():
|
||||
|
@ -282,6 +282,11 @@ class IPRangeBulkEditForm(NetBoxModelBulkEditForm):
|
||||
queryset=Role.objects.all(),
|
||||
required=False
|
||||
)
|
||||
mark_utilized = forms.NullBooleanField(
|
||||
required=False,
|
||||
widget=BulkEditNullBooleanSelect(),
|
||||
label=_('Treat as 100% utilized')
|
||||
)
|
||||
description = forms.CharField(
|
||||
max_length=200,
|
||||
required=False
|
||||
@ -293,7 +298,7 @@ class IPRangeBulkEditForm(NetBoxModelBulkEditForm):
|
||||
|
||||
model = IPRange
|
||||
fieldsets = (
|
||||
(None, ('status', 'role', 'vrf', 'tenant', 'description')),
|
||||
(None, ('status', 'role', 'vrf', 'tenant', 'mark_utilized', 'description')),
|
||||
)
|
||||
nullable_fields = (
|
||||
'vrf', 'tenant', 'role', 'description', 'comments',
|
||||
|
@ -223,7 +223,8 @@ class IPRangeImportForm(NetBoxModelImportForm):
|
||||
class Meta:
|
||||
model = IPRange
|
||||
fields = (
|
||||
'start_address', 'end_address', 'vrf', 'tenant', 'status', 'role', 'description', 'comments', 'tags',
|
||||
'start_address', 'end_address', 'vrf', 'tenant', 'status', 'role', 'mark_utilized', 'description',
|
||||
'comments', 'tags',
|
||||
)
|
||||
|
||||
|
||||
|
@ -253,7 +253,7 @@ class IPRangeFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
||||
model = IPRange
|
||||
fieldsets = (
|
||||
(None, ('q', 'filter_id', 'tag')),
|
||||
('Attriubtes', ('family', 'vrf_id', 'status', 'role_id')),
|
||||
('Attriubtes', ('family', 'vrf_id', 'status', 'role_id', 'mark_utilized')),
|
||||
('Tenant', ('tenant_group_id', 'tenant_id')),
|
||||
)
|
||||
family = forms.ChoiceField(
|
||||
@ -277,6 +277,13 @@ class IPRangeFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
||||
null_option='None',
|
||||
label=_('Role')
|
||||
)
|
||||
mark_utilized = forms.NullBooleanField(
|
||||
required=False,
|
||||
label=_('Marked as 100% utilized'),
|
||||
widget=forms.Select(
|
||||
choices=BOOLEAN_WITH_BLANK_CHOICES
|
||||
)
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
||||
|
@ -288,15 +288,15 @@ class IPRangeForm(TenancyForm, NetBoxModelForm):
|
||||
comments = CommentField()
|
||||
|
||||
fieldsets = (
|
||||
('IP Range', ('vrf', 'start_address', 'end_address', 'role', 'status', 'description', 'tags')),
|
||||
('IP Range', ('vrf', 'start_address', 'end_address', 'role', 'status', 'mark_utilized', 'description', 'tags')),
|
||||
('Tenancy', ('tenant_group', 'tenant')),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = IPRange
|
||||
fields = [
|
||||
'vrf', 'start_address', 'end_address', 'status', 'role', 'tenant_group', 'tenant', 'description',
|
||||
'comments', 'tags',
|
||||
'vrf', 'start_address', 'end_address', 'status', 'role', 'tenant_group', 'tenant', 'mark_utilized',
|
||||
'description', 'comments', 'tags',
|
||||
]
|
||||
|
||||
|
||||
|
18
netbox/ipam/migrations/0065_iprange_mark_utilized.py
Normal file
18
netbox/ipam/migrations/0065_iprange_mark_utilized.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.1.7 on 2023-02-28 14:51
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('ipam', '0064_asnrange'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='iprange',
|
||||
name='mark_utilized',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
@ -511,6 +511,10 @@ class IPRange(PrimaryModel):
|
||||
null=True,
|
||||
help_text=_('The primary function of this range')
|
||||
)
|
||||
mark_utilized = models.BooleanField(
|
||||
default=False,
|
||||
help_text=_("Treat as 100% utilized")
|
||||
)
|
||||
|
||||
clone_fields = (
|
||||
'vrf', 'tenant', 'status', 'role', 'description',
|
||||
@ -652,6 +656,9 @@ class IPRange(PrimaryModel):
|
||||
"""
|
||||
Determine the utilization of the range and return it as a percentage.
|
||||
"""
|
||||
if self.mark_utilized:
|
||||
return 100
|
||||
|
||||
# Compile an IPSet to avoid counting duplicate IPs
|
||||
child_count = netaddr.IPSet([
|
||||
ip.address.ip for ip in self.get_child_ips()
|
||||
|
@ -275,6 +275,9 @@ class IPRangeTable(TenancyColumnsMixin, NetBoxTable):
|
||||
role = tables.Column(
|
||||
linkify=True
|
||||
)
|
||||
mark_utilized = columns.BooleanColumn(
|
||||
verbose_name='Marked Utilized'
|
||||
)
|
||||
utilization = columns.UtilizationColumn(
|
||||
accessor='utilization',
|
||||
orderable=False
|
||||
@ -288,7 +291,7 @@ class IPRangeTable(TenancyColumnsMixin, NetBoxTable):
|
||||
model = IPRange
|
||||
fields = (
|
||||
'pk', 'id', 'start_address', 'end_address', 'size', 'vrf', 'status', 'role', 'tenant', 'tenant_group',
|
||||
'utilization', 'description', 'comments', 'tags', 'created', 'last_updated',
|
||||
'mark_utilized', 'utilization', 'description', 'comments', 'tags', 'created', 'last_updated',
|
||||
)
|
||||
default_columns = (
|
||||
'pk', 'start_address', 'end_address', 'size', 'vrf', 'status', 'role', 'tenant', 'description',
|
||||
|
@ -30,7 +30,12 @@
|
||||
<tr>
|
||||
<th scope="row">Utilization</th>
|
||||
<td>
|
||||
{% utilization_graph object.utilization %}
|
||||
{% if object.mark_utilized %}
|
||||
{% utilization_graph 100 warning_threshold=0 danger_threshold=0 %}
|
||||
<small>(Marked fully utilized)</small>
|
||||
{% else %}
|
||||
{% utilization_graph object.utilization %}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
Reference in New Issue
Block a user