mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-22 03:56:53 -06:00
commit
50a451eddc
@ -1120,6 +1120,8 @@ class ConsoleServerPort(models.Model):
|
|||||||
def clean(self):
|
def clean(self):
|
||||||
|
|
||||||
# Check that the parent device's DeviceType is a console server
|
# Check that the parent device's DeviceType is a console server
|
||||||
|
if self.device is None:
|
||||||
|
raise ValidationError("Console server ports must be assigned to devices.")
|
||||||
device_type = self.device.device_type
|
device_type = self.device.device_type
|
||||||
if not device_type.is_console_server:
|
if not device_type.is_console_server:
|
||||||
raise ValidationError("The {} {} device type not support assignment of console server ports.".format(
|
raise ValidationError("The {} {} device type not support assignment of console server ports.".format(
|
||||||
@ -1194,6 +1196,8 @@ class PowerOutlet(models.Model):
|
|||||||
def clean(self):
|
def clean(self):
|
||||||
|
|
||||||
# Check that the parent device's DeviceType is a PDU
|
# Check that the parent device's DeviceType is a PDU
|
||||||
|
if self.device is None:
|
||||||
|
raise ValidationError("Power outlets must be assigned to devices.")
|
||||||
device_type = self.device.device_type
|
device_type = self.device.device_type
|
||||||
if not device_type.is_pdu:
|
if not device_type.is_pdu:
|
||||||
raise ValidationError("The {} {} device type not support assignment of power outlets.".format(
|
raise ValidationError("The {} {} device type not support assignment of power outlets.".format(
|
||||||
@ -1257,11 +1261,12 @@ class Interface(models.Model):
|
|||||||
def clean(self):
|
def clean(self):
|
||||||
|
|
||||||
# Check that the parent device's DeviceType is a network device
|
# Check that the parent device's DeviceType is a network device
|
||||||
device_type = self.device.device_type
|
if self.device is not None:
|
||||||
if not device_type.is_network_device:
|
device_type = self.device.device_type
|
||||||
raise ValidationError("The {} {} device type not support assignment of network interfaces.".format(
|
if not device_type.is_network_device:
|
||||||
device_type.manufacturer, device_type
|
raise ValidationError("The {} {} device type not support assignment of network interfaces.".format(
|
||||||
))
|
device_type.manufacturer, device_type
|
||||||
|
))
|
||||||
|
|
||||||
# An Interface must belong to a Device *or* to a VirtualMachine
|
# An Interface must belong to a Device *or* to a VirtualMachine
|
||||||
if self.device and self.virtual_machine:
|
if self.device and self.virtual_machine:
|
||||||
|
@ -689,7 +689,7 @@ class IPAddressBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
|
|||||||
|
|
||||||
|
|
||||||
class IPAddressAssignForm(BootstrapMixin, forms.Form):
|
class IPAddressAssignForm(BootstrapMixin, forms.Form):
|
||||||
vrf = forms.ModelChoiceField(queryset=VRF.objects.all(), required=False, label='VRF')
|
vrf = forms.ModelChoiceField(queryset=VRF.objects.all(), required=False, label='VRF', empty_label='Global')
|
||||||
address = forms.CharField(label='IP Address')
|
address = forms.CharField(label='IP Address')
|
||||||
|
|
||||||
|
|
||||||
|
@ -304,6 +304,16 @@ class Prefix(CreatedUpdatedModel, CustomFieldModel):
|
|||||||
|
|
||||||
return available_ips
|
return available_ips
|
||||||
|
|
||||||
|
def get_first_available_ip(self):
|
||||||
|
"""
|
||||||
|
Return the first available IP within the prefix (or None).
|
||||||
|
"""
|
||||||
|
available_ips = self.get_available_ips()
|
||||||
|
if available_ips:
|
||||||
|
return '{}/{}'.format(next(available_ips.__iter__()), self.prefix.prefixlen)
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
def get_utilization(self):
|
def get_utilization(self):
|
||||||
"""
|
"""
|
||||||
Determine the utilization of the prefix and return it as a percentage. For Prefixes with a status of
|
Determine the utilization of the prefix and return it as a percentage. For Prefixes with a status of
|
||||||
|
@ -13,7 +13,7 @@ except ImportError:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
VERSION = '2.2.5'
|
VERSION = '2.2.6'
|
||||||
|
|
||||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
@ -35,8 +35,22 @@ footer p {
|
|||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Collapse the nav menu on displays less than 1200px wide */
|
/* Hide the username in the navigation menu on displays less than 1400px wide */
|
||||||
|
@media (max-width: 1399px) {
|
||||||
|
#navbar_user {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide the search bar in the navigation menu on displays less than 1200px wide */
|
||||||
@media (max-width: 1199px) {
|
@media (max-width: 1199px) {
|
||||||
|
#navbar_search {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Collapse the nav menu on displays less than 960px wide */
|
||||||
|
@media (max-width: 959px) {
|
||||||
.navbar-header {
|
.navbar-header {
|
||||||
float: none;
|
float: none;
|
||||||
}
|
}
|
||||||
@ -72,12 +86,8 @@ footer p {
|
|||||||
.collapse.in {
|
.collapse.in {
|
||||||
display:block !important;
|
display:block !important;
|
||||||
}
|
}
|
||||||
}
|
#navbar_user {
|
||||||
|
display: inline;
|
||||||
/* Hide the nav search bar on displays less than 1600px wide */
|
|
||||||
@media (max-width: 1599px) {
|
|
||||||
#navbar_search {
|
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,10 @@
|
|||||||
<span class="fa fa-plus" aria-hidden="true"></span>
|
<span class="fa fa-plus" aria-hidden="true"></span>
|
||||||
Add a circuit type
|
Add a circuit type
|
||||||
</a>
|
</a>
|
||||||
|
<a href="{% url 'circuits:circuittype_import' %}" class="btn btn-info">
|
||||||
|
<span class="fa fa-download" aria-hidden="true"></span>
|
||||||
|
Import circuit types
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<h1>{% block title %}Circuit Types{% endblock %}</h1>
|
<h1>{% block title %}Circuit Types{% endblock %}</h1>
|
||||||
|
@ -8,6 +8,10 @@
|
|||||||
<span class="fa fa-plus" aria-hidden="true"></span>
|
<span class="fa fa-plus" aria-hidden="true"></span>
|
||||||
Add a device role
|
Add a device role
|
||||||
</a>
|
</a>
|
||||||
|
<a href="{% url 'dcim:devicerole_import' %}" class="btn btn-info">
|
||||||
|
<span class="fa fa-download" aria-hidden="true"></span>
|
||||||
|
Import device roles
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<h1>{% block title %}Device Roles{% endblock %}</h1>
|
<h1>{% block title %}Device Roles{% endblock %}</h1>
|
||||||
|
@ -8,6 +8,10 @@
|
|||||||
<span class="fa fa-plus" aria-hidden="true"></span>
|
<span class="fa fa-plus" aria-hidden="true"></span>
|
||||||
Add a platform
|
Add a platform
|
||||||
</a>
|
</a>
|
||||||
|
<a href="{% url 'dcim:platform_import' %}" class="btn btn-info">
|
||||||
|
<span class="fa fa-download" aria-hidden="true"></span>
|
||||||
|
Import platforms
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<h1>{% block title %}Platforms{% endblock %}</h1>
|
<h1>{% block title %}Platforms{% endblock %}</h1>
|
||||||
|
@ -8,6 +8,10 @@
|
|||||||
<span class="fa fa-plus" aria-hidden="true"></span>
|
<span class="fa fa-plus" aria-hidden="true"></span>
|
||||||
Add a rack role
|
Add a rack role
|
||||||
</a>
|
</a>
|
||||||
|
<a href="{% url 'dcim:rackrole_import' %}" class="btn btn-info">
|
||||||
|
<span class="fa fa-download" aria-hidden="true"></span>
|
||||||
|
Import rack roles
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<h1>{% block title %}Rack Roles{% endblock %}</h1>
|
<h1>{% block title %}Rack Roles{% endblock %}</h1>
|
||||||
|
@ -379,7 +379,9 @@
|
|||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
<li class="dropdown">
|
<li class="dropdown">
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" title="{{ request.user }}" role="button" aria-haspopup="true" aria-expanded="false">
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" title="{{ request.user }}" role="button" aria-haspopup="true" aria-expanded="false">
|
||||||
{{ request.user|truncatechars:"30" }} <span class="caret"></span>
|
<i class="fa fa-user"></i>
|
||||||
|
<span id="navbar_user">{{ request.user|truncatechars:"30" }}</span>
|
||||||
|
<span class="caret"></span>
|
||||||
</a>
|
</a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="{% url 'user:profile' %}"><i class="fa fa-user"></i> Profile</a></li>
|
<li><a href="{% url 'user:profile' %}"><i class="fa fa-user"></i> Profile</a></li>
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
{% if perms.ipam.add_ipaddress %}
|
{% if perms.ipam.add_ipaddress %}
|
||||||
<a href="{% url 'ipam:ipaddress_add' %}?address={{ prefix.prefix }}{% if prefix.vrf %}&vrf={{ prefix.vrf.pk }}{% endif %}{% if prefix.tenant %}&tenant={{ prefix.tenant.pk }}{% endif %}" class="btn btn-success">
|
<a href="{% url 'ipam:ipaddress_add' %}?address={{ prefix.get_first_available_ip }}{% if prefix.vrf %}&vrf={{ prefix.vrf.pk }}{% endif %}{% if prefix.tenant %}&tenant={{ prefix.tenant.pk }}{% endif %}" class="btn btn-success">
|
||||||
<span class="fa fa-plus" aria-hidden="true"></span>
|
<span class="fa fa-plus" aria-hidden="true"></span>
|
||||||
Add an IP Address
|
Add an IP Address
|
||||||
</a>
|
</a>
|
||||||
|
@ -20,6 +20,10 @@
|
|||||||
<span class="fa fa-plus" aria-hidden="true"></span>
|
<span class="fa fa-plus" aria-hidden="true"></span>
|
||||||
Add a RIR
|
Add a RIR
|
||||||
</a>
|
</a>
|
||||||
|
<a href="{% url 'ipam:rir_import' %}" class="btn btn-info">
|
||||||
|
<span class="fa fa-download" aria-hidden="true"></span>
|
||||||
|
Import RIRs
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<h1>{% block title %}RIRs{% endblock %}</h1>
|
<h1>{% block title %}RIRs{% endblock %}</h1>
|
||||||
|
@ -8,6 +8,10 @@
|
|||||||
<span class="fa fa-plus" aria-hidden="true"></span>
|
<span class="fa fa-plus" aria-hidden="true"></span>
|
||||||
Add a role
|
Add a role
|
||||||
</a>
|
</a>
|
||||||
|
<a href="{% url 'ipam:role_import' %}" class="btn btn-info">
|
||||||
|
<span class="fa fa-download" aria-hidden="true"></span>
|
||||||
|
Import roles
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<h1>{% block title %}Prefix/VLAN Roles{% endblock %}</h1>
|
<h1>{% block title %}Prefix/VLAN Roles{% endblock %}</h1>
|
||||||
|
@ -8,6 +8,10 @@
|
|||||||
<span class="fa fa-plus" aria-hidden="true"></span>
|
<span class="fa fa-plus" aria-hidden="true"></span>
|
||||||
Add a VLAN group
|
Add a VLAN group
|
||||||
</a>
|
</a>
|
||||||
|
<a href="{% url 'ipam:vlangroup_import' %}" class="btn btn-info">
|
||||||
|
<span class="fa fa-download" aria-hidden="true"></span>
|
||||||
|
Import VLAN groups
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<h1>{% block title %}VLAN Groups{% endblock %}</h1>
|
<h1>{% block title %}VLAN Groups{% endblock %}</h1>
|
||||||
|
@ -8,6 +8,10 @@
|
|||||||
<span class="fa fa-plus" aria-hidden="true"></span>
|
<span class="fa fa-plus" aria-hidden="true"></span>
|
||||||
Add a secret role
|
Add a secret role
|
||||||
</a>
|
</a>
|
||||||
|
<a href="{% url 'secrets:secretrole_import' %}" class="btn btn-info">
|
||||||
|
<span class="fa fa-download" aria-hidden="true"></span>
|
||||||
|
Import secret roles
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<h1>{% block title %}Secret Roles{% endblock %}</h1>
|
<h1>{% block title %}Secret Roles{% endblock %}</h1>
|
||||||
|
@ -8,6 +8,10 @@
|
|||||||
<span class="fa fa-plus" aria-hidden="true"></span>
|
<span class="fa fa-plus" aria-hidden="true"></span>
|
||||||
Add a tenant group
|
Add a tenant group
|
||||||
</a>
|
</a>
|
||||||
|
<a href="{% url 'tenancy:tenantgroup_import' %}" class="btn btn-info">
|
||||||
|
<span class="fa fa-download" aria-hidden="true"></span>
|
||||||
|
Import tenant groups
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<h1>{% block title %}Tenant Groups{% endblock %}</h1>
|
<h1>{% block title %}Tenant Groups{% endblock %}</h1>
|
||||||
|
@ -8,6 +8,10 @@
|
|||||||
<span class="fa fa-plus" aria-hidden="true"></span>
|
<span class="fa fa-plus" aria-hidden="true"></span>
|
||||||
Add a cluster group
|
Add a cluster group
|
||||||
</a>
|
</a>
|
||||||
|
<a href="{% url 'virtualization:clustergroup_import' %}" class="btn btn-info">
|
||||||
|
<span class="fa fa-download" aria-hidden="true"></span>
|
||||||
|
Import cluster groups
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<h1>{% block title %}Cluster Groups{% endblock %}</h1>
|
<h1>{% block title %}Cluster Groups{% endblock %}</h1>
|
||||||
|
@ -8,6 +8,10 @@
|
|||||||
<span class="fa fa-plus" aria-hidden="true"></span>
|
<span class="fa fa-plus" aria-hidden="true"></span>
|
||||||
Add a cluster type
|
Add a cluster type
|
||||||
</a>
|
</a>
|
||||||
|
<a href="{% url 'virtualization:clustertype_import' %}" class="btn btn-info">
|
||||||
|
<span class="fa fa-download" aria-hidden="true"></span>
|
||||||
|
Import cluster types
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<h1>{% block title %}Cluster Types{% endblock %}</h1>
|
<h1>{% block title %}Cluster Types{% endblock %}</h1>
|
||||||
|
Loading…
Reference in New Issue
Block a user