mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-14 09:51:22 -06:00
Merge branch 'develop' into feature
This commit is contained in:
commit
22908a12e9
2
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
@ -14,7 +14,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: NetBox version
|
label: NetBox version
|
||||||
description: What version of NetBox are you currently running?
|
description: What version of NetBox are you currently running?
|
||||||
placeholder: v3.1.9
|
placeholder: v3.1.10
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
|
2
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
2
.github/ISSUE_TEMPLATE/feature_request.yaml
vendored
@ -14,7 +14,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
label: NetBox version
|
label: NetBox version
|
||||||
description: What version of NetBox are you currently running?
|
description: What version of NetBox are you currently running?
|
||||||
placeholder: v3.1.9
|
placeholder: v3.1.10
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
# NetBox v3.1
|
# NetBox v3.1
|
||||||
|
|
||||||
## v3.1.10 (FUTURE)
|
## v3.1.11 (FUTURE)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## v3.1.10 (2022-03-25)
|
||||||
|
|
||||||
### Enhancements
|
### Enhancements
|
||||||
|
|
||||||
|
* [#8232](https://github.com/netbox-community/netbox/issues/8232) - Use a different color for 100% utilization bars
|
||||||
* [#8457](https://github.com/netbox-community/netbox/issues/8457) - Enable adding non-racked devices from site & location views
|
* [#8457](https://github.com/netbox-community/netbox/issues/8457) - Enable adding non-racked devices from site & location views
|
||||||
* [#8553](https://github.com/netbox-community/netbox/issues/8553) - Add missing object types to global search form
|
* [#8553](https://github.com/netbox-community/netbox/issues/8553) - Add missing object types to global search form
|
||||||
* [#8575](https://github.com/netbox-community/netbox/issues/8575) - Add rack columns to cables list
|
* [#8575](https://github.com/netbox-community/netbox/issues/8575) - Add rack columns to cables list
|
||||||
* [#8645](https://github.com/netbox-community/netbox/issues/8645) - Enable filtering objects by assigned contacts & contact roles
|
* [#8645](https://github.com/netbox-community/netbox/issues/8645) - Enable filtering objects by assigned contacts & contact roles
|
||||||
|
* [#8926](https://github.com/netbox-community/netbox/issues/8926) - Add device type, role columns to device bay table
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
|
@ -409,7 +409,7 @@ class Rack(NetBoxModel):
|
|||||||
available_units.remove(u)
|
available_units.remove(u)
|
||||||
|
|
||||||
occupied_unit_count = self.u_height - len(available_units)
|
occupied_unit_count = self.u_height - len(available_units)
|
||||||
percentage = int(float(occupied_unit_count) / self.u_height * 100)
|
percentage = float(occupied_unit_count) / self.u_height * 100
|
||||||
|
|
||||||
return percentage
|
return percentage
|
||||||
|
|
||||||
|
@ -679,6 +679,15 @@ class DeviceBayTable(DeviceComponentTable):
|
|||||||
'args': [Accessor('device_id')],
|
'args': [Accessor('device_id')],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
device_role = columns.ColoredLabelColumn(
|
||||||
|
accessor=Accessor('installed_device__device_role'),
|
||||||
|
verbose_name='Role'
|
||||||
|
)
|
||||||
|
device_type = tables.Column(
|
||||||
|
accessor=Accessor('installed_device__device_type'),
|
||||||
|
linkify=True,
|
||||||
|
verbose_name='Type'
|
||||||
|
)
|
||||||
status = tables.TemplateColumn(
|
status = tables.TemplateColumn(
|
||||||
template_code=DEVICEBAY_STATUS,
|
template_code=DEVICEBAY_STATUS,
|
||||||
order_by=Accessor('installed_device__status')
|
order_by=Accessor('installed_device__status')
|
||||||
@ -693,7 +702,7 @@ class DeviceBayTable(DeviceComponentTable):
|
|||||||
class Meta(DeviceComponentTable.Meta):
|
class Meta(DeviceComponentTable.Meta):
|
||||||
model = DeviceBay
|
model = DeviceBay
|
||||||
fields = (
|
fields = (
|
||||||
'pk', 'id', 'name', 'device', 'label', 'status', 'installed_device', 'description', 'tags',
|
'pk', 'id', 'name', 'device', 'label', 'status', 'device_role', 'device_type', 'installed_device', 'description', 'tags',
|
||||||
'created', 'last_updated',
|
'created', 'last_updated',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -244,7 +244,7 @@ class Aggregate(GetAvailablePrefixesMixin, NetBoxModel):
|
|||||||
"""
|
"""
|
||||||
queryset = Prefix.objects.filter(prefix__net_contained_or_equal=str(self.prefix))
|
queryset = Prefix.objects.filter(prefix__net_contained_or_equal=str(self.prefix))
|
||||||
child_prefixes = netaddr.IPSet([p.prefix for p in queryset])
|
child_prefixes = netaddr.IPSet([p.prefix for p in queryset])
|
||||||
utilization = int(float(child_prefixes.size) / self.prefix.size * 100)
|
utilization = float(child_prefixes.size) / self.prefix.size * 100
|
||||||
|
|
||||||
return min(utilization, 100)
|
return min(utilization, 100)
|
||||||
|
|
||||||
@ -542,7 +542,7 @@ class Prefix(GetAvailablePrefixesMixin, NetBoxModel):
|
|||||||
vrf=self.vrf
|
vrf=self.vrf
|
||||||
)
|
)
|
||||||
child_prefixes = netaddr.IPSet([p.prefix for p in queryset])
|
child_prefixes = netaddr.IPSet([p.prefix for p in queryset])
|
||||||
utilization = int(float(child_prefixes.size) / self.prefix.size * 100)
|
utilization = float(child_prefixes.size) / self.prefix.size * 100
|
||||||
else:
|
else:
|
||||||
# Compile an IPSet to avoid counting duplicate IPs
|
# Compile an IPSet to avoid counting duplicate IPs
|
||||||
child_ips = netaddr.IPSet(
|
child_ips = netaddr.IPSet(
|
||||||
@ -552,7 +552,7 @@ class Prefix(GetAvailablePrefixesMixin, NetBoxModel):
|
|||||||
prefix_size = self.prefix.size
|
prefix_size = self.prefix.size
|
||||||
if self.prefix.version == 4 and self.prefix.prefixlen < 31 and not self.is_pool:
|
if self.prefix.version == 4 and self.prefix.prefixlen < 31 and not self.is_pool:
|
||||||
prefix_size -= 2
|
prefix_size -= 2
|
||||||
utilization = int(float(child_ips.size) / prefix_size * 100)
|
utilization = float(child_ips.size) / prefix_size * 100
|
||||||
|
|
||||||
return min(utilization, 100)
|
return min(utilization, 100)
|
||||||
|
|
||||||
|
@ -204,11 +204,11 @@ class TestPrefix(TestCase):
|
|||||||
IPAddress.objects.bulk_create([
|
IPAddress.objects.bulk_create([
|
||||||
IPAddress(address=IPNetwork(f'10.0.0.{i}/24')) for i in range(1, 33)
|
IPAddress(address=IPNetwork(f'10.0.0.{i}/24')) for i in range(1, 33)
|
||||||
])
|
])
|
||||||
self.assertEqual(prefix.get_utilization(), 12) # 12.5% utilization
|
self.assertEqual(prefix.get_utilization(), 32 / 254 * 100) # ~12.5% utilization
|
||||||
|
|
||||||
# Create a child range with 32 additional IPs
|
# Create a child range with 32 additional IPs
|
||||||
IPRange.objects.create(start_address=IPNetwork('10.0.0.33/24'), end_address=IPNetwork('10.0.0.64/24'))
|
IPRange.objects.create(start_address=IPNetwork('10.0.0.33/24'), end_address=IPNetwork('10.0.0.64/24'))
|
||||||
self.assertEqual(prefix.get_utilization(), 25) # 25% utilization
|
self.assertEqual(prefix.get_utilization(), 64 / 254 * 100) # ~25% utilization
|
||||||
|
|
||||||
#
|
#
|
||||||
# Uniqueness enforcement tests
|
# Uniqueness enforcement tests
|
||||||
|
@ -12,10 +12,10 @@
|
|||||||
class="progress-bar {{ bar_class }}"
|
class="progress-bar {{ bar_class }}"
|
||||||
style="width: {{ utilization }}%;"
|
style="width: {{ utilization }}%;"
|
||||||
>
|
>
|
||||||
{% if utilization >= 25 %}{{ utilization }}%{% endif %}
|
{% if utilization >= 25 %}{{ utilization|floatformat:0 }}%{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if utilization < 25 %}
|
{% if utilization < 25 %}
|
||||||
<span class="ps-1">{{ utilization }}%</span>
|
<span class="ps-1">{{ utilization|floatformat:0 }}%</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -264,7 +264,9 @@ def utilization_graph(utilization, warning_threshold=75, danger_threshold=90):
|
|||||||
"""
|
"""
|
||||||
Display a horizontal bar graph indicating a percentage of utilization.
|
Display a horizontal bar graph indicating a percentage of utilization.
|
||||||
"""
|
"""
|
||||||
if danger_threshold and utilization >= danger_threshold:
|
if utilization == 100:
|
||||||
|
bar_class = 'bg-secondary'
|
||||||
|
elif danger_threshold and utilization >= danger_threshold:
|
||||||
bar_class = 'bg-danger'
|
bar_class = 'bg-danger'
|
||||||
elif warning_threshold and utilization >= warning_threshold:
|
elif warning_threshold and utilization >= warning_threshold:
|
||||||
bar_class = 'bg-warning'
|
bar_class = 'bg-warning'
|
||||||
|
@ -19,7 +19,7 @@ gunicorn==20.1.0
|
|||||||
Jinja2==3.0.3
|
Jinja2==3.0.3
|
||||||
Markdown==3.3.6
|
Markdown==3.3.6
|
||||||
markdown-include==0.6.0
|
markdown-include==0.6.0
|
||||||
mkdocs-material==8.2.5
|
mkdocs-material==8.2.7
|
||||||
mkdocstrings==0.17.0
|
mkdocstrings==0.17.0
|
||||||
netaddr==0.8.0
|
netaddr==0.8.0
|
||||||
Pillow==9.0.1
|
Pillow==9.0.1
|
||||||
@ -27,7 +27,7 @@ psycopg2-binary==2.9.3
|
|||||||
PyYAML==6.0
|
PyYAML==6.0
|
||||||
social-auth-app-django==5.0.0
|
social-auth-app-django==5.0.0
|
||||||
social-auth-core==4.2.0
|
social-auth-core==4.2.0
|
||||||
svgwrite==1.4.1
|
svgwrite==1.4.2
|
||||||
tablib==3.2.0
|
tablib==3.2.0
|
||||||
tzdata==2021.5
|
tzdata==2021.5
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user