Jelajahi Sumber

Merge branch 'develop' into feature

jeremystretch 3 tahun lalu
induk
melakukan
5a77791f9d

+ 3 - 0
docs/installation/3-netbox.md

@@ -225,6 +225,9 @@ Once NetBox has been configured, we're ready to proceed with the actual installa
 * Builds the documentation locally (for offline use)
 * Aggregate static resource files on disk
 
+!!! warning
+    If you still have a Python virtual environment active from a previous installation step, disable it now by running the `deactivate` command. This will avoid errors on systems where `sudo` has been configured to preserve the user's current environment.
+
 ```no-highlight
 sudo /opt/netbox/upgrade.sh
 ```

+ 12 - 0
docs/release-notes/version-3.3.md

@@ -2,6 +2,18 @@
 
 ## v3.3.10 (FUTURE)
 
+### Enhancements
+
+* [#10748](https://github.com/netbox-community/netbox/issues/10748) - Add provider selection field for provider networks to circuit termination edit view
+* [#11119](https://github.com/netbox-community/netbox/issues/11119) - Enable filtering L2VPNs by slug
+
+### Bug Fixes
+
+* [#11041](https://github.com/netbox-community/netbox/issues/11041) - Correct power utilization percentage precision
+* [#11087](https://github.com/netbox-community/netbox/issues/11087) - Fix background color of bottom banner content
+* [#11101](https://github.com/netbox-community/netbox/issues/11101) - Correct circuits count under site view
+* [#11128](https://github.com/netbox-community/netbox/issues/11128) - Disable ordering changelog table by object to avoid exception
+
 ---
 
 ## v3.3.9 (2022-11-30)

+ 14 - 2
netbox/circuits/forms/model_forms.py

@@ -145,16 +145,28 @@ class CircuitTerminationForm(NetBoxModelForm):
         },
         required=False
     )
+    provider_network_provider = DynamicModelChoiceField(
+        queryset=Provider.objects.all(),
+        required=False,
+        label='Provider',
+        initial_params={
+            'networks': 'provider_network'
+        }
+    )
     provider_network = DynamicModelChoiceField(
         queryset=ProviderNetwork.objects.all(),
+        query_params={
+            'provider_id': '$provider_network_provider',
+        },
         required=False
     )
 
     class Meta:
         model = CircuitTermination
         fields = [
-            'provider', 'circuit', 'term_side', 'region', 'site_group', 'site', 'provider_network', 'mark_connected',
-            'port_speed', 'upstream_speed', 'xconnect_id', 'pp_info', 'description', 'tags',
+            'provider', 'circuit', 'term_side', 'region', 'site_group', 'site', 'provider_network_provider',
+            'provider_network', 'mark_connected', 'port_speed', 'upstream_speed', 'xconnect_id', 'pp_info',
+            'description', 'tags',
         ]
         help_texts = {
             'port_speed': _("Physical circuit speed"),

+ 1 - 1
netbox/dcim/views.py

@@ -391,7 +391,7 @@ class SiteView(generic.ObjectView):
                 scope_id=instance.pk
             ).count(),
             'vlan_count': VLAN.objects.restrict(request.user, 'view').filter(site=instance).count(),
-            'circuit_count': Circuit.objects.restrict(request.user, 'view').filter(terminations__site=instance).count(),
+            'circuit_count': Circuit.objects.restrict(request.user, 'view').filter(terminations__site=instance).distinct().count(),
             'vm_count': VirtualMachine.objects.restrict(request.user, 'view').filter(cluster__site=instance).count(),
         }
         locations = Location.objects.add_related_count(

+ 2 - 1
netbox/extras/tables/tables.py

@@ -215,7 +215,8 @@ class ObjectChangeTable(NetBoxTable):
     object_repr = tables.TemplateColumn(
         accessor=tables.A('changed_object'),
         template_code=OBJECTCHANGE_OBJECT,
-        verbose_name='Object'
+        verbose_name='Object',
+        orderable=False
     )
     request_id = tables.TemplateColumn(
         template_code=OBJECTCHANGE_REQUEST_ID,

+ 1 - 1
netbox/ipam/filtersets.py

@@ -962,7 +962,7 @@ class L2VPNFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
 
     class Meta:
         model = L2VPN
-        fields = ['id', 'identifier', 'name', 'type', 'description']
+        fields = ['id', 'identifier', 'name', 'slug', 'type', 'description']
 
     def search(self, queryset, name, value):
         if not value.strip():

+ 4 - 0
netbox/ipam/tests/test_filtersets.py

@@ -1505,6 +1505,10 @@ class L2VPNTestCase(TestCase, ChangeLoggedFilterSetTests):
         params = {'name': ['L2VPN 1', 'L2VPN 2']}
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
 
+    def test_slug(self):
+        params = {'slug': ['l2vpn-1', 'l2vpn-2']}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+
     def test_identifier(self):
         params = {'identifier': ['65001', '65002']}
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)

+ 6 - 6
netbox/templates/base/layout.html

@@ -102,14 +102,14 @@ Blocks:
               {% block content %}{% endblock %}
             </div>
           {% endblock %}
+          {# Bottom banner #}
+          {% if config.BANNER_BOTTOM %}
+            <div class="text-center mx-3">
+              {{ config.BANNER_BOTTOM|safe }}
+            </div>
+          {% endif %}
         </div>
 
-        {% if config.BANNER_BOTTOM %}
-          <div class="text-center mx-3">
-            {{ config.BANNER_BOTTOM|safe }}
-          </div>
-        {% endif %}
-
         {# BS5 pop-up modals #}
         {% block modals %}{% endblock %}
 

+ 1 - 0
netbox/templates/circuits/circuittermination_edit.html

@@ -32,6 +32,7 @@
           {% render_field form.site %}
         </div>
         <div class="tab-pane{% if providernetwork_tab_active %} active{% endif %}" id="providernetwork">
+          {% render_field form.provider_network_provider %}
           {% render_field form.provider_network %}
         </div>
       </div>

+ 1 - 1
netbox/templates/circuits/inc/circuit_termination.html

@@ -81,7 +81,7 @@
           {% else %}
             <tr>
               <td>Provider Network</td>
-              <td>{{ termination.provider_network|linkify }}</td>
+              <td>{{ termination.provider_network.provider|linkify }} / {{ termination.provider_network|linkify }}</td>
             </tr>
           {% endif %}
             <tr>

+ 2 - 1
netbox/utilities/templatetags/helpers.py

@@ -140,7 +140,8 @@ def percentage(x, y):
     """
     if x is None or y is None:
         return None
-    return round(x / y * 100)
+
+    return round(x / y * 100, 1)
 
 
 @register.filter()