Browse Source

Merge branch 'develop' into develop-2.3

Jeremy Stretch 7 years ago
parent
commit
ca77e4545a

+ 10 - 5
netbox/dcim/models.py

@@ -1121,6 +1121,8 @@ class ConsoleServerPort(models.Model):
     def clean(self):
 
         # 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
         if not device_type.is_console_server:
             raise ValidationError("The {} {} device type not support assignment of console server ports.".format(
@@ -1195,6 +1197,8 @@ class PowerOutlet(models.Model):
     def clean(self):
 
         # 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
         if not device_type.is_pdu:
             raise ValidationError("The {} {} device type not support assignment of power outlets.".format(
@@ -1272,11 +1276,12 @@ class Interface(models.Model):
     def clean(self):
 
         # Check that the parent device's DeviceType is a network device
-        device_type = self.device.device_type
-        if not device_type.is_network_device:
-            raise ValidationError("The {} {} device type not support assignment of network interfaces.".format(
-                device_type.manufacturer, device_type
-            ))
+        if self.device is not None:
+            device_type = self.device.device_type
+            if not device_type.is_network_device:
+                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
         if self.device and self.virtual_machine:

+ 1 - 1
netbox/ipam/forms.py

@@ -689,7 +689,7 @@ class IPAddressBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
 
 
 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')
 
 

+ 10 - 0
netbox/ipam/models.py

@@ -319,6 +319,16 @@ class Prefix(CreatedUpdatedModel, CustomFieldModel):
 
         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):
         """
         Determine the utilization of the prefix and return it as a percentage. For Prefixes with a status of

+ 1 - 1
netbox/netbox/settings.py

@@ -22,7 +22,7 @@ if sys.version_info[0] < 3:
         DeprecationWarning
     )
 
-VERSION = '2.2.6-dev'
+VERSION = '2.2.7-dev'
 
 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 

+ 17 - 7
netbox/project-static/css/base.css

@@ -35,8 +35,22 @@ footer p {
     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) {
+    #navbar_search {
+        display: none;
+    }
+}
+
+/* Collapse the nav menu on displays less than 960px wide */
+@media (max-width: 959px) {
     .navbar-header {
         float: none;
     }
@@ -72,12 +86,8 @@ footer p {
     .collapse.in {
         display:block !important;
     }
-}
-
-/* Hide the nav search bar on displays less than 1600px wide */
-@media (max-width: 1599px) {
-    #navbar_search {
-        display: none;
+    #navbar_user {
+        display: inline;
     }
 }
 

+ 4 - 0
netbox/templates/circuits/circuittype_list.html

@@ -8,6 +8,10 @@
             <span class="fa fa-plus" aria-hidden="true"></span>
             Add a circuit type
         </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 %}
 </div>
 <h1>{% block title %}Circuit Types{% endblock %}</h1>

+ 4 - 0
netbox/templates/dcim/devicerole_list.html

@@ -8,6 +8,10 @@
             <span class="fa fa-plus" aria-hidden="true"></span>
             Add a device role
         </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 %}
 </div>
 <h1>{% block title %}Device Roles{% endblock %}</h1>

+ 4 - 0
netbox/templates/dcim/platform_list.html

@@ -8,6 +8,10 @@
             <span class="fa fa-plus" aria-hidden="true"></span>
             Add a platform
         </a>
+        <a href="{% url 'dcim:platform_import' %}" class="btn btn-info">
+            <span class="fa fa-download" aria-hidden="true"></span>
+            Import platforms
+        </a>
     {% endif %}
 </div>
 <h1>{% block title %}Platforms{% endblock %}</h1>

+ 4 - 0
netbox/templates/dcim/rackrole_list.html

@@ -8,6 +8,10 @@
             <span class="fa fa-plus" aria-hidden="true"></span>
             Add a rack role
         </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 %}
 </div>
 <h1>{% block title %}Rack Roles{% endblock %}</h1>

+ 3 - 1
netbox/templates/inc/nav_menu.html

@@ -379,7 +379,9 @@
                 {% if request.user.is_authenticated %}
                     <li class="dropdown">
                         <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>
                         <ul class="dropdown-menu">
                             <li><a href="{% url 'user:profile' %}"><i class="fa fa-user"></i> Profile</a></li>

+ 1 - 1
netbox/templates/ipam/inc/prefix_header.html

@@ -23,7 +23,7 @@
 </div>
 <div class="pull-right">
     {% 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>
 			Add an IP Address
 		</a>

+ 4 - 0
netbox/templates/ipam/rir_list.html

@@ -20,6 +20,10 @@
             <span class="fa fa-plus" aria-hidden="true"></span>
             Add a RIR
         </a>
+        <a href="{% url 'ipam:rir_import' %}" class="btn btn-info">
+            <span class="fa fa-download" aria-hidden="true"></span>
+            Import RIRs
+        </a>
     {% endif %}
 </div>
 <h1>{% block title %}RIRs{% endblock %}</h1>

+ 4 - 0
netbox/templates/ipam/role_list.html

@@ -8,6 +8,10 @@
             <span class="fa fa-plus" aria-hidden="true"></span>
             Add a role
         </a>
+        <a href="{% url 'ipam:role_import' %}" class="btn btn-info">
+            <span class="fa fa-download" aria-hidden="true"></span>
+            Import roles
+        </a>
     {% endif %}
 </div>
 <h1>{% block title %}Prefix/VLAN Roles{% endblock %}</h1>

+ 4 - 0
netbox/templates/ipam/vlangroup_list.html

@@ -8,6 +8,10 @@
             <span class="fa fa-plus" aria-hidden="true"></span>
             Add a VLAN group
         </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 %}
 </div>
 <h1>{% block title %}VLAN Groups{% endblock %}</h1>

+ 4 - 0
netbox/templates/secrets/secretrole_list.html

@@ -8,6 +8,10 @@
             <span class="fa fa-plus" aria-hidden="true"></span>
             Add a secret role
         </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 %}
 </div>
 <h1>{% block title %}Secret Roles{% endblock %}</h1>

+ 4 - 0
netbox/templates/tenancy/tenantgroup_list.html

@@ -8,6 +8,10 @@
             <span class="fa fa-plus" aria-hidden="true"></span>
             Add a tenant group
         </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 %}
 </div>
 <h1>{% block title %}Tenant Groups{% endblock %}</h1>

+ 4 - 0
netbox/templates/virtualization/clustergroup_list.html

@@ -8,6 +8,10 @@
             <span class="fa fa-plus" aria-hidden="true"></span>
             Add a cluster group
         </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 %}
 </div>
 <h1>{% block title %}Cluster Groups{% endblock %}</h1>

+ 4 - 0
netbox/templates/virtualization/clustertype_list.html

@@ -8,6 +8,10 @@
             <span class="fa fa-plus" aria-hidden="true"></span>
             Add a cluster type
         </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 %}
 </div>
 <h1>{% block title %}Cluster Types{% endblock %}</h1>