From a3f172fc77c08a5af2f5f683a281d73b8403fb16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Est=C3=A9vez?= Date: Fri, 25 Feb 2022 11:30:13 -0500 Subject: [PATCH 01/94] Conflicting documentation on remote default group In the current documentation we have two seemingly conflicting sentences: * REMOTE_AUTH_DEFAULT_GROUPS: (Requires REMOTE_AUTH_ENABLED.) * REMOTE_AUTH_ENABLED: (REMOTE_AUTH_DEFAULT_GROUPS will not function if REMOTE_AUTH_ENABLED is enabled) --- docs/configuration/remote-authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration/remote-authentication.md b/docs/configuration/remote-authentication.md index 73d29415b..2c3a7002f 100644 --- a/docs/configuration/remote-authentication.md +++ b/docs/configuration/remote-authentication.md @@ -43,7 +43,7 @@ A mapping of permissions to assign a new user account when created using remote Default: `False` -NetBox can be configured to support remote user authentication by inferring user authentication from an HTTP header set by the HTTP reverse proxy (e.g. nginx or Apache). Set this to `True` to enable this functionality. (Local authentication will still take effect as a fallback.) (`REMOTE_AUTH_DEFAULT_GROUPS` will not function if `REMOTE_AUTH_ENABLED` is enabled) +NetBox can be configured to support remote user authentication by inferring user authentication from an HTTP header set by the HTTP reverse proxy (e.g. nginx or Apache). Set this to `True` to enable this functionality. (Local authentication will still take effect as a fallback.) (`REMOTE_AUTH_DEFAULT_GROUPS` will not function if `REMOTE_AUTH_ENABLED` is disabled) --- From 3edff89a4dd141d9e448c6625eaa056947589428 Mon Sep 17 00:00:00 2001 From: Alex Gittings Date: Mon, 14 Mar 2022 17:57:33 +0000 Subject: [PATCH 02/94] Fixes: #8866 - Does not perform API Select Search if a django peramiter has not been replaced --- netbox/project-static/dist/netbox.js | Bin 375602 -> 375655 bytes netbox/project-static/dist/netbox.js.map | Bin 344930 -> 344977 bytes .../src/select/api/apiSelect.ts | 9 ++++++--- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/netbox/project-static/dist/netbox.js b/netbox/project-static/dist/netbox.js index 45abd19e6209158d93fbe083fce3e1de985a9f5e..be807c2deebe794c033929da381b3550b567e34e 100644 GIT binary patch delta 95 zcmdn=P3-wMv4$4L7N!>F7M3lnFC#^Y^7JzEl5xJ*lrQU pYQQ3poS#>mpOdPWlb^1Un5U^TJtK})jb8^@I4^H|Zyf8=7y!DbBCG%a delta 53 zcmaFEOQv4$4L7N!>F7M3lnFC(Y_jbshj?iaf=$L}B`xNLGdI JFXLG2VgN{H6gmI^ diff --git a/netbox/project-static/dist/netbox.js.map b/netbox/project-static/dist/netbox.js.map index c7e20fe9ae4893f6bbbbd26ccb95f35b556214cb..40cfad2fc5a029c9ae3415cce7db65a19da7e1b5 100644 GIT binary patch delta 126 zcmaFVCOWZQw4sHug{g&k3rpD_F-J#7Zyk3>M^Bw#N5^0te@EvGCmrAE<$qXgSt1>S z{kHG;!;-r-lnd7uIh&7ajv!ueQ${A=@ U>GlmQtbXi_Ronk_vnHDZ0P_qc+W-In delta 79 zcmbQ(F8ZiVw4sHug{g&k3rpD_M(^o8e^_i;!X5p+wx9jOlEKX4=;-J<)tOb3HPO-2 j+<9vwYbXn6R)tfQvyQ)G_V)WMtbXi_1>5y_Sd+~GU;Y`< diff --git a/netbox/project-static/src/select/api/apiSelect.ts b/netbox/project-static/src/select/api/apiSelect.ts index 5cd2c0055..be8a86631 100644 --- a/netbox/project-static/src/select/api/apiSelect.ts +++ b/netbox/project-static/src/select/api/apiSelect.ts @@ -557,9 +557,12 @@ export class APISelect { private async handleSearch(event: Event) { const { value: q } = event.target as HTMLInputElement; const url = queryString.stringifyUrl({ url: this.queryUrl, query: { q } }); - await this.fetchOptions(url, 'merge'); - this.slim.data.search(q); - this.slim.render(); + if (!url.includes(`{{`)) { + await this.fetchOptions(url, 'merge'); + this.slim.data.search(q); + this.slim.render(); + } + return; } /** From f45e64c756050d947aa8c5196b516fff8b5dcb08 Mon Sep 17 00:00:00 2001 From: fmlshai <82157941+fmlshai@users.noreply.github.com> Date: Wed, 23 Mar 2022 14:38:26 +0100 Subject: [PATCH 03/94] Fix #8785 - allow wildcard dns records Added * to the DNSValidator regex to allow wildcard domains like *.example.com --- netbox/ipam/validators.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netbox/ipam/validators.py b/netbox/ipam/validators.py index 879e20e6a..08f62ad35 100644 --- a/netbox/ipam/validators.py +++ b/netbox/ipam/validators.py @@ -24,7 +24,7 @@ class MinPrefixLengthValidator(BaseValidator): DNSValidator = RegexValidator( - regex='^[0-9A-Za-z._-]+$', - message='Only alphanumeric characters, hyphens, periods, and underscores are allowed in DNS names', + regex='^[0-9A-Za-z*._-]+$', + message='Only alphanumeric characters, asterisks, hyphens, periods, and underscores are allowed in DNS names', code='invalid' ) From 934493bf5f4ca36e255012d24e0d9f35e300dfd5 Mon Sep 17 00:00:00 2001 From: neope <58367950+apellini@users.noreply.github.com> Date: Fri, 25 Mar 2022 08:35:57 +0100 Subject: [PATCH 04/94] #8830 Adding ClusterXL Adding ClusterCL Choice to FHRP Group --- netbox/ipam/choices.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/netbox/ipam/choices.py b/netbox/ipam/choices.py index 647a82810..b95a77a5b 100644 --- a/netbox/ipam/choices.py +++ b/netbox/ipam/choices.py @@ -100,6 +100,7 @@ class IPAddressRoleChoices(ChoiceSet): ROLE_HSRP = 'hsrp' ROLE_GLBP = 'glbp' ROLE_CARP = 'carp' + ROLE_CLUSTERXL = 'clusterxl' CHOICES = ( (ROLE_LOOPBACK, 'Loopback'), @@ -108,6 +109,7 @@ class IPAddressRoleChoices(ChoiceSet): (ROLE_VIP, 'VIP'), (ROLE_VRRP, 'VRRP'), (ROLE_HSRP, 'HSRP'), + (ROLE_CLUSTERXL, 'ClusterXL'), (ROLE_GLBP, 'GLBP'), (ROLE_CARP, 'CARP'), ) @@ -119,6 +121,7 @@ class IPAddressRoleChoices(ChoiceSet): ROLE_VIP: 'success', ROLE_VRRP: 'success', ROLE_HSRP: 'success', + ROLE_CLUSTERXL: 'success', ROLE_GLBP: 'success', ROLE_CARP: 'success', } From 1cef513f6c2584a3b2961f135b8e5ad3d6336536 Mon Sep 17 00:00:00 2001 From: neope <58367950+apellini@users.noreply.github.com> Date: Fri, 25 Mar 2022 19:41:35 +0100 Subject: [PATCH 05/94] Adding ClusterXL as FHRPGroupProtocolChoices Adding in choices group standard, checkpoint and cisco and ungroupped other. --- netbox/ipam/choices.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/netbox/ipam/choices.py b/netbox/ipam/choices.py index b95a77a5b..7e704a975 100644 --- a/netbox/ipam/choices.py +++ b/netbox/ipam/choices.py @@ -100,7 +100,6 @@ class IPAddressRoleChoices(ChoiceSet): ROLE_HSRP = 'hsrp' ROLE_GLBP = 'glbp' ROLE_CARP = 'carp' - ROLE_CLUSTERXL = 'clusterxl' CHOICES = ( (ROLE_LOOPBACK, 'Loopback'), @@ -109,7 +108,6 @@ class IPAddressRoleChoices(ChoiceSet): (ROLE_VIP, 'VIP'), (ROLE_VRRP, 'VRRP'), (ROLE_HSRP, 'HSRP'), - (ROLE_CLUSTERXL, 'ClusterXL'), (ROLE_GLBP, 'GLBP'), (ROLE_CARP, 'CARP'), ) @@ -121,7 +119,6 @@ class IPAddressRoleChoices(ChoiceSet): ROLE_VIP: 'success', ROLE_VRRP: 'success', ROLE_HSRP: 'success', - ROLE_CLUSTERXL: 'success', ROLE_GLBP: 'success', ROLE_CARP: 'success', } @@ -138,14 +135,22 @@ class FHRPGroupProtocolChoices(ChoiceSet): PROTOCOL_HSRP = 'hsrp' PROTOCOL_GLBP = 'glbp' PROTOCOL_CARP = 'carp' + PROTOCOL_CLUSTERXL = 'clusterxl' PROTOCOL_OTHER = 'other' CHOICES = ( - (PROTOCOL_VRRP2, 'VRRPv2'), - (PROTOCOL_VRRP3, 'VRRPv3'), - (PROTOCOL_HSRP, 'HSRP'), - (PROTOCOL_GLBP, 'GLBP'), - (PROTOCOL_CARP, 'CARP'), + ('Standard', ( + (PROTOCOL_VRRP2, 'VRRPv2'), + (PROTOCOL_VRRP3, 'VRRPv3'), + (PROTOCOL_CARP, 'CARP'), + ), + ('CheckPoint', ( + (PROTOCOL_CLUSTERXL, 'ClusterXL'), + ), + ('Cisco', ( + (PROTOCOL_HSRP, 'HSRP'), + (PROTOCOL_GLBP, 'GLBP'), + ), (PROTOCOL_OTHER, 'Other'), ) From a1808a54a492f5cb710bbcfe75b57ffa7e387b9a Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 28 Mar 2022 09:13:15 -0400 Subject: [PATCH 06/94] Fixes #8974: Use monospace font for text areas in config revision form --- docs/release-notes/version-3.1.md | 4 ++++ netbox/extras/admin.py | 3 +++ netbox/netbox/config/parameters.py | 26 +++++++++++++++++++++----- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/docs/release-notes/version-3.1.md b/docs/release-notes/version-3.1.md index df9c9c7bb..13e2161b4 100644 --- a/docs/release-notes/version-3.1.md +++ b/docs/release-notes/version-3.1.md @@ -2,6 +2,10 @@ ## v3.1.11 (FUTURE) +### Enhancements + +* [#8974](https://github.com/netbox-community/netbox/issues/8974) - Use monospace font for text areas in config revision form + --- ## v3.1.10 (2022-03-25) diff --git a/netbox/extras/admin.py b/netbox/extras/admin.py index b6ee01db9..047f723ad 100644 --- a/netbox/extras/admin.py +++ b/netbox/extras/admin.py @@ -23,15 +23,18 @@ class ConfigRevisionAdmin(admin.ModelAdmin): }), ('Banners', { 'fields': ('BANNER_LOGIN', 'BANNER_TOP', 'BANNER_BOTTOM'), + 'classes': ('monospace',), }), ('Pagination', { 'fields': ('PAGINATE_COUNT', 'MAX_PAGE_SIZE'), }), ('Validation', { 'fields': ('CUSTOM_VALIDATORS',), + 'classes': ('monospace',), }), ('NAPALM', { 'fields': ('NAPALM_USERNAME', 'NAPALM_PASSWORD', 'NAPALM_TIMEOUT', 'NAPALM_ARGS'), + 'classes': ('monospace',), }), ('Miscellaneous', { 'fields': ('MAINTENANCE_MODE', 'GRAPHQL_ENABLED', 'CHANGELOG_RETENTION', 'MAPS_URL'), diff --git a/netbox/netbox/config/parameters.py b/netbox/netbox/config/parameters.py index 22dbac143..7da40e063 100644 --- a/netbox/netbox/config/parameters.py +++ b/netbox/netbox/config/parameters.py @@ -22,7 +22,9 @@ PARAMS = ( default='', description="Additional content to display on the login page", field_kwargs={ - 'widget': forms.Textarea(), + 'widget': forms.Textarea( + attrs={'class': 'vLargeTextField'} + ), }, ), ConfigParam( @@ -31,7 +33,9 @@ PARAMS = ( default='', description="Additional content to display at the top of every page", field_kwargs={ - 'widget': forms.Textarea(), + 'widget': forms.Textarea( + attrs={'class': 'vLargeTextField'} + ), }, ), ConfigParam( @@ -40,7 +44,9 @@ PARAMS = ( default='', description="Additional content to display at the bottom of every page", field_kwargs={ - 'widget': forms.Textarea(), + 'widget': forms.Textarea( + attrs={'class': 'vLargeTextField'} + ), }, ), @@ -109,7 +115,12 @@ PARAMS = ( label='Custom validators', default={}, description="Custom validation rules (JSON)", - field=forms.JSONField + field=forms.JSONField, + field_kwargs={ + 'widget': forms.Textarea( + attrs={'class': 'vLargeTextField'} + ), + }, ), # NAPALM @@ -137,7 +148,12 @@ PARAMS = ( label='NAPALM arguments', default={}, description="Additional arguments to pass when invoking a NAPALM driver (as JSON data)", - field=forms.JSONField + field=forms.JSONField, + field_kwargs={ + 'widget': forms.Textarea( + attrs={'class': 'vLargeTextField'} + ), + }, ), # Miscellaneous From e0344e92511a42caf31d15ae9688ecf5e9db3e2a Mon Sep 17 00:00:00 2001 From: fmlshai <82157941+fmlshai@users.noreply.github.com> Date: Mon, 28 Mar 2022 15:20:19 +0200 Subject: [PATCH 07/94] Update validators.py Updated DNSValidator regex --- netbox/ipam/validators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/ipam/validators.py b/netbox/ipam/validators.py index 08f62ad35..50faea8b8 100644 --- a/netbox/ipam/validators.py +++ b/netbox/ipam/validators.py @@ -24,7 +24,7 @@ class MinPrefixLengthValidator(BaseValidator): DNSValidator = RegexValidator( - regex='^[0-9A-Za-z*._-]+$', + regex=r'^([0-9A-Za-z_-]+|\*)(\.[0-9A-Za-z_-]+)*\.?$', message='Only alphanumeric characters, asterisks, hyphens, periods, and underscores are allowed in DNS names', code='invalid' ) From 37781bd2087250806173a10dc15a8e412bcf7eb3 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 28 Mar 2022 09:37:33 -0400 Subject: [PATCH 08/94] Fix parentheses --- netbox/ipam/choices.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/netbox/ipam/choices.py b/netbox/ipam/choices.py index 7e704a975..6c23dd8c0 100644 --- a/netbox/ipam/choices.py +++ b/netbox/ipam/choices.py @@ -143,14 +143,14 @@ class FHRPGroupProtocolChoices(ChoiceSet): (PROTOCOL_VRRP2, 'VRRPv2'), (PROTOCOL_VRRP3, 'VRRPv3'), (PROTOCOL_CARP, 'CARP'), - ), + )), ('CheckPoint', ( (PROTOCOL_CLUSTERXL, 'ClusterXL'), - ), + )), ('Cisco', ( (PROTOCOL_HSRP, 'HSRP'), (PROTOCOL_GLBP, 'GLBP'), - ), + )), (PROTOCOL_OTHER, 'Other'), ) From 48b7294ff1227172fbc8667ba84bd22793d52d5f Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 28 Mar 2022 10:35:00 -0400 Subject: [PATCH 09/94] #8785: Tweak regex validator to avoid creating no-op migration file --- netbox/ipam/migrations/0001_squashed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/ipam/migrations/0001_squashed.py b/netbox/ipam/migrations/0001_squashed.py index 17d2f8123..545fd46c6 100644 --- a/netbox/ipam/migrations/0001_squashed.py +++ b/netbox/ipam/migrations/0001_squashed.py @@ -50,7 +50,7 @@ class Migration(migrations.Migration): ('status', models.CharField(default='active', max_length=50)), ('role', models.CharField(blank=True, max_length=50)), ('assigned_object_id', models.PositiveIntegerField(blank=True, null=True)), - ('dns_name', models.CharField(blank=True, max_length=255, validators=[django.core.validators.RegexValidator(code='invalid', message='Only alphanumeric characters, hyphens, periods, and underscores are allowed in DNS names', regex='^[0-9A-Za-z._-]+$')])), + ('dns_name', models.CharField(blank=True, max_length=255, validators=[django.core.validators.RegexValidator(code='invalid', message='Only alphanumeric characters, asterisks, hyphens, periods, and underscores are allowed in DNS names', regex='^([0-9A-Za-z_-]+|\\*)(\\.[0-9A-Za-z_-]+)*\\.?$')])), ('description', models.CharField(blank=True, max_length=200)), ], options={ From 894665b067616cb7b29c4522460f55daf53f3e61 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 28 Mar 2022 10:35:49 -0400 Subject: [PATCH 10/94] Changelog for #8785, #8830 --- docs/release-notes/version-3.1.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/release-notes/version-3.1.md b/docs/release-notes/version-3.1.md index 13e2161b4..303a05cae 100644 --- a/docs/release-notes/version-3.1.md +++ b/docs/release-notes/version-3.1.md @@ -4,6 +4,8 @@ ### Enhancements +* [#8785](https://github.com/netbox-community/netbox/issues/8785) - Permit wildcard values in IP address DNS names +* [#8830](https://github.com/netbox-community/netbox/issues/8830) - Add Checkpoint ClusterXL protocol for FHRP groups * [#8974](https://github.com/netbox-community/netbox/issues/8974) - Use monospace font for text areas in config revision form --- From 340ff824879791e0bea41f8c5634d3999ba4257a Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 28 Mar 2022 13:22:43 -0400 Subject: [PATCH 11/94] Fixes #8970: Permit nested inventory item templates on device types --- docs/release-notes/version-3.2.md | 1 + netbox/dcim/forms/models.py | 9 +-- netbox/dcim/tables/devicetypes.py | 4 +- .../dcim/component_template_create.html | 56 ++++++++++--------- 4 files changed, 36 insertions(+), 34 deletions(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index c45436d07..e3332d706 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -151,6 +151,7 @@ Where it is desired to limit the range of available VLANs within a group, users * [#8845](https://github.com/netbox-community/netbox/issues/8845) - Correct default ASN formatting in table * [#8869](https://github.com/netbox-community/netbox/issues/8869) - Fix NoReverseMatch exception when displaying tag w/assignments * [#8872](https://github.com/netbox-community/netbox/issues/8872) - Enable filtering by custom object fields +* [#8970](https://github.com/netbox-community/netbox/issues/8970) - Permit nested inventory item templates on device types ### Other Changes diff --git a/netbox/dcim/forms/models.py b/netbox/dcim/forms/models.py index 6cdcb372c..6054ee7bf 100644 --- a/netbox/dcim/forms/models.py +++ b/netbox/dcim/forms/models.py @@ -1025,10 +1025,10 @@ class DeviceBayTemplateForm(BootstrapMixin, forms.ModelForm): class InventoryItemTemplateForm(BootstrapMixin, forms.ModelForm): parent = DynamicModelChoiceField( - queryset=InventoryItem.objects.all(), + queryset=InventoryItemTemplate.objects.all(), required=False, query_params={ - 'device_id': '$device' + 'devicetype_id': '$device_type' } ) role = DynamicModelChoiceField( @@ -1050,11 +1050,6 @@ class InventoryItemTemplateForm(BootstrapMixin, forms.ModelForm): widget=forms.HiddenInput ) - fieldsets = ( - ('Inventory Item', ('device_type', 'parent', 'name', 'label', 'role', 'description')), - ('Hardware', ('manufacturer', 'part_id')), - ) - class Meta: model = InventoryItemTemplate fields = [ diff --git a/netbox/dcim/tables/devicetypes.py b/netbox/dcim/tables/devicetypes.py index e5e703ee0..f5f5ed7bf 100644 --- a/netbox/dcim/tables/devicetypes.py +++ b/netbox/dcim/tables/devicetypes.py @@ -241,5 +241,7 @@ class InventoryItemTemplateTable(ComponentTemplateTable): class Meta(ComponentTemplateTable.Meta): model = InventoryItemTemplate - fields = ('pk', 'name', 'label', 'role', 'manufacturer', 'part_id', 'component', 'description', 'actions') + fields = ( + 'pk', 'name', 'label', 'parent', 'role', 'manufacturer', 'part_id', 'component', 'description', 'actions', + ) empty_text = "None" diff --git a/netbox/templates/dcim/component_template_create.html b/netbox/templates/dcim/component_template_create.html index b3c5332b9..d164db872 100644 --- a/netbox/templates/dcim/component_template_create.html +++ b/netbox/templates/dcim/component_template_create.html @@ -2,33 +2,37 @@ {% load form_helpers %} {% block form %} -
-
- + {% if form.module_type %} +
+
+ +
-
-
-
- {% render_field replication_form.device_type %} +
+
+ {% render_field replication_form.device_type %} +
+
+ {% render_field replication_form.module_type %} +
-
- {% render_field replication_form.module_type %} -
- {% block replication_fields %} - {% render_field replication_form.name_pattern %} - {% render_field replication_form.label_pattern %} - {% endblock replication_fields %} -
+ {% else %} + {% render_field replication_form.device_type %} + {% endif %} + {% block replication_fields %} + {% render_field replication_form.name_pattern %} + {% render_field replication_form.label_pattern %} + {% endblock replication_fields %} {{ block.super }} {% endblock form %} From 227bac7c60103df596b47176562d16e577e13b81 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 28 Mar 2022 13:34:37 -0400 Subject: [PATCH 12/94] Fixes #8976: Add missing object_type field on CustomField REST API serializer --- docs/release-notes/version-3.2.md | 1 + netbox/extras/api/serializers.py | 9 ++++++--- netbox/extras/forms/models.py | 4 ++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index e3332d706..2b85e6eda 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -152,6 +152,7 @@ Where it is desired to limit the range of available VLANs within a group, users * [#8869](https://github.com/netbox-community/netbox/issues/8869) - Fix NoReverseMatch exception when displaying tag w/assignments * [#8872](https://github.com/netbox-community/netbox/issues/8872) - Enable filtering by custom object fields * [#8970](https://github.com/netbox-community/netbox/issues/8970) - Permit nested inventory item templates on device types +* [#8976](https://github.com/netbox-community/netbox/issues/8976) - Add missing `object_type` field on CustomField REST API serializer ### Other Changes diff --git a/netbox/extras/api/serializers.py b/netbox/extras/api/serializers.py index 36b307b39..f4cf6f66a 100644 --- a/netbox/extras/api/serializers.py +++ b/netbox/extras/api/serializers.py @@ -78,15 +78,18 @@ class CustomFieldSerializer(ValidatedModelSerializer): many=True ) type = ChoiceField(choices=CustomFieldTypeChoices) + object_type = ContentTypeField( + queryset=ContentType.objects.all() + ) filter_logic = ChoiceField(choices=CustomFieldFilterLogicChoices, required=False) data_type = serializers.SerializerMethodField() class Meta: model = CustomField fields = [ - 'id', 'url', 'display', 'content_types', 'type', 'data_type', 'name', 'label', 'description', 'required', - 'filter_logic', 'default', 'weight', 'validation_minimum', 'validation_maximum', 'validation_regex', - 'choices', 'created', 'last_updated', + 'id', 'url', 'display', 'content_types', 'type', 'object_type', 'data_type', 'name', 'label', 'description', + 'required', 'filter_logic', 'default', 'weight', 'validation_minimum', 'validation_maximum', + 'validation_regex', 'choices', 'created', 'last_updated', ] def get_data_type(self, obj): diff --git a/netbox/extras/forms/models.py b/netbox/extras/forms/models.py index 071f80453..78b627662 100644 --- a/netbox/extras/forms/models.py +++ b/netbox/extras/forms/models.py @@ -48,6 +48,10 @@ class CustomFieldForm(BootstrapMixin, forms.ModelForm): class Meta: model = CustomField fields = '__all__' + help_texts = { + 'type': "The type of data stored in this field. For object/multi-object fields, select the related object " + "type below." + } widgets = { 'type': StaticSelect(), 'filter_logic': StaticSelect(), From bf50134d94a73006fcb69ef8207dc1fb1105e71c Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 28 Mar 2022 14:18:45 -0400 Subject: [PATCH 13/94] #8976: Set required=False on serializer field --- netbox/extras/api/serializers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/netbox/extras/api/serializers.py b/netbox/extras/api/serializers.py index f4cf6f66a..5ab8beb13 100644 --- a/netbox/extras/api/serializers.py +++ b/netbox/extras/api/serializers.py @@ -79,7 +79,8 @@ class CustomFieldSerializer(ValidatedModelSerializer): ) type = ChoiceField(choices=CustomFieldTypeChoices) object_type = ContentTypeField( - queryset=ContentType.objects.all() + queryset=ContentType.objects.all(), + required=False ) filter_logic = ChoiceField(choices=CustomFieldFilterLogicChoices, required=False) data_type = serializers.SerializerMethodField() From b7e2ea1ca5ad734373fe442425cd9b0b019b7467 Mon Sep 17 00:00:00 2001 From: Stephan Blanke Date: Mon, 28 Mar 2022 20:37:00 +0200 Subject: [PATCH 14/94] Closes #8163: Add bridge members panel to interface view --- netbox/dcim/models/device_components.py | 4 ++++ netbox/dcim/views.py | 9 +++++++++ netbox/templates/dcim/interface.html | 7 +++++++ 3 files changed, 20 insertions(+) diff --git a/netbox/dcim/models/device_components.py b/netbox/dcim/models/device_components.py index e105bd804..b20df82b7 100644 --- a/netbox/dcim/models/device_components.py +++ b/netbox/dcim/models/device_components.py @@ -762,6 +762,10 @@ class Interface(ComponentModel, BaseInterface, LinkTermination, PathEndpoint): def is_lag(self): return self.type == InterfaceTypeChoices.TYPE_LAG + @property + def is_bridge(self): + return self.type == InterfaceTypeChoices.TYPE_BRIDGE + @property def link(self): return self.cable or self.wireless_link diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 6697a44cc..f5e71fd23 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -1776,6 +1776,14 @@ class InterfaceView(generic.ObjectView): orderable=False ) + # Get bridge interfaces + bridge_interfaces = Interface.objects.restrict(request.user, 'view').filter(bridge=instance) + bridge_interfaces_tables = tables.InterfaceTable( + bridge_interfaces, + exclude=('device', 'parent'), + orderable=False + ) + # Get child interfaces child_interfaces = Interface.objects.restrict(request.user, 'view').filter(parent=instance) child_interfaces_tables = tables.InterfaceTable( @@ -1800,6 +1808,7 @@ class InterfaceView(generic.ObjectView): return { 'ipaddress_table': ipaddress_table, + 'bridge_interfaces_table': bridge_interfaces_tables, 'child_interfaces_table': child_interfaces_tables, 'vlan_table': vlan_table, } diff --git a/netbox/templates/dcim/interface.html b/netbox/templates/dcim/interface.html index 5eaa99c3f..bf1445a1c 100644 --- a/netbox/templates/dcim/interface.html +++ b/netbox/templates/dcim/interface.html @@ -467,6 +467,13 @@ {% include 'inc/panel_table.html' with table=vlan_table heading="VLANs" %}
+ {% if object.is_bridge %} +
+
+ {% include 'inc/panel_table.html' with table=bridge_interfaces_table heading="Bridge Interfaces" %} +
+
+ {% endif %}
{% include 'inc/panel_table.html' with table=child_interfaces_table heading="Child Interfaces" %} From ff780177d0810652b102e91dbd25006091e81305 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 29 Mar 2022 16:01:10 -0400 Subject: [PATCH 15/94] Clean up exception templates --- netbox/templates/exceptions/import_error.html | 30 +++++++++---------- .../exceptions/permission_error.html | 16 +++++----- .../exceptions/programming_error.html | 26 ++++++++-------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/netbox/templates/exceptions/import_error.html b/netbox/templates/exceptions/import_error.html index e8ee7ae2c..3e25b5369 100644 --- a/netbox/templates/exceptions/import_error.html +++ b/netbox/templates/exceptions/import_error.html @@ -1,19 +1,19 @@ {% extends '500.html' %} {% block message %} -

- A module import error occurred during this request. Common causes include the following: -

-

- Missing required packages - This installation of NetBox might be - missing one or more required Python packages. These packages are listed in requirements.txt and - local_requirements.txt, and are normally installed as part of the installation or upgrade process. - To verify installed packages, run pip freeze from the console and compare the output to the list of - required packages. -

-

- WSGI service not restarted after upgrade - If this installation - has recently been upgraded, check that the WSGI service (e.g. gunicorn or uWSGI) has been restarted. This - ensures that the new code is running. -

+

+ A module import error occurred during this request. Common causes include the following: +

+

+ Missing required packages - This installation of NetBox might be + missing one or more required Python packages. These packages are listed in requirements.txt and + local_requirements.txt, and are normally installed as part of the installation or upgrade process. To + verify installed packages, run pip freeze from the console and compare the output to the list of + required packages. +

+

+ WSGI service not restarted after upgrade - If this installation has + recently been upgraded, check that the WSGI service (e.g. gunicorn or uWSGI) has been restarted. This ensures that + the new code is running. +

{% endblock message %} diff --git a/netbox/templates/exceptions/permission_error.html b/netbox/templates/exceptions/permission_error.html index dcff62bf9..6108fde52 100644 --- a/netbox/templates/exceptions/permission_error.html +++ b/netbox/templates/exceptions/permission_error.html @@ -1,12 +1,12 @@ {% extends '500.html' %} {% block message %} -

- A file permission error was detected while processing this request. Common causes include the following: -

-

- Insufficient write permission to the media root - The configured - media root is {{ settings.MEDIA_ROOT }}. Ensure that the user NetBox runs as has access to write - files to all locations within this path. -

+

+ A file permission error was detected while processing this request. Common causes include the following: +

+

+ Insufficient write permission to the media root - The configured + media root is {{ settings.MEDIA_ROOT }}. Ensure that the user NetBox runs as has access to write files + to all locations within this path. +

{% endblock message %} diff --git a/netbox/templates/exceptions/programming_error.html b/netbox/templates/exceptions/programming_error.html index 3b9e84567..38175b187 100644 --- a/netbox/templates/exceptions/programming_error.html +++ b/netbox/templates/exceptions/programming_error.html @@ -1,17 +1,17 @@ {% extends '500.html' %} {% block message %} -

- A database programming error was detected while processing this request. Common causes include the following: -

-

- Database migrations missing - When upgrading to a new NetBox release, the upgrade script must - be run to apply any new database migrations. You can run migrations manually by executing - python3 manage.py migrate from the command line. -

-

- Unsupported PostgreSQL version - Ensure that PostgreSQL version 9.6 or higher is in use. You - can check this by connecting to the database using NetBox's credentials and issuing a query for - SELECT VERSION(). -

+

+ A database programming error was detected while processing this request. Common causes include the following: +

+

+ Database migrations missing - When upgrading to a new NetBox release, + the upgrade script must be run to apply any new database migrations. You can run migrations manually by executing + python3 manage.py migrate from the command line. +

+

+ Unsupported PostgreSQL version - Ensure that PostgreSQL version 10 + or later is in use. You can check this by connecting to the database using NetBox's credentials and issuing a query + for SELECT VERSION(). +

{% endblock message %} From dadec9d3cb1d2fffa788e83fd1754a7c7bedc823 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 30 Mar 2022 13:03:08 -0400 Subject: [PATCH 16/94] Add instruction for checking out an older release --- docs/installation/upgrading.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/installation/upgrading.md b/docs/installation/upgrading.md index d7f7156c8..c619cf241 100644 --- a/docs/installation/upgrading.md +++ b/docs/installation/upgrading.md @@ -6,7 +6,7 @@ Prior to upgrading your NetBox instance, be sure to carefully review all [releas ## Update Dependencies to Required Versions -NetBox v3.0 and later requires the following: +NetBox v3.0 and later require the following: | Dependency | Minimum Version | |------------|-----------------| @@ -67,6 +67,11 @@ sudo git checkout master sudo git pull origin master ``` +!!! info "Checking out an older release" + If you need to upgrade to an older version rather than the current stable release, you can check out any valid [git tag](https://github.com/netbox-community/netbox/tags), each of which represents a release. For example, to checkout the code for NetBox v2.11.11, do: + + sudo git checkout v2.11.11 + ## Run the Upgrade Script Once the new code is in place, verify that any optional Python packages required by your deployment (e.g. `napalm` or `django-auth-ldap`) are listed in `local_requirements.txt`. Then, run the upgrade script: From db535e6453a1502e67630fb7795e5126ae601212 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 30 Mar 2022 14:05:27 -0400 Subject: [PATCH 17/94] Closes #8436: Update token permissions documentation --- docs/models/users/token.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/models/users/token.md b/docs/models/users/token.md index d0e0f8609..d98b51369 100644 --- a/docs/models/users/token.md +++ b/docs/models/users/token.md @@ -3,7 +3,7 @@ A token is a unique identifier mapped to a NetBox user account. Each user may have one or more tokens which he or she can use for authentication when making REST API requests. To create a token, navigate to the API tokens page under your user profile. !!! note - The creation and modification of API tokens can be restricted per user by an administrator. If you don't see an option to create an API token, ask an administrator to grant you access. + All users can create and manage REST API tokens under the user control panel in the UI. The ability to view, add, change, or delete tokens via the REST API itself is controlled by the relevant model permissions, assigned to users and/or groups in the admin UI. These permissions should be used with great care to avoid accidentally permitting a user to create tokens for other user accounts. Each token contains a 160-bit key represented as 40 hexadecimal characters. When creating a token, you'll typically leave the key field blank so that a random key will be automatically generated. However, NetBox allows you to specify a key in case you need to restore a previously deleted token to operation. From 1eaf55c555875eab9b2c3b1255f6f2d53678701a Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 30 Mar 2022 14:14:49 -0400 Subject: [PATCH 18/94] Closes #8336: Add note about referening object in custom link template --- docs/models/extras/customlink.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/models/extras/customlink.md b/docs/models/extras/customlink.md index 7fd510841..b9b731751 100644 --- a/docs/models/extras/customlink.md +++ b/docs/models/extras/customlink.md @@ -2,7 +2,7 @@ Custom links allow users to display arbitrary hyperlinks to external content within NetBox object views. These are helpful for cross-referencing related records in systems outside NetBox. For example, you might create a custom link on the device view which links to the current device in a Network Monitoring System (NMS). -Custom links are created by navigating to Customization > Custom Links. Each link is associated with a particular NetBox object type (site, device, prefix, etc.) and will be displayed on relevant views. Each link has display text and a URL, and data from the Netbox item being viewed can be included in the link using [Jinja2 template code](https://jinja2docs.readthedocs.io/en/stable/) through the variable `obj`, and custom fields through `obj.cf`. +Custom links are created by navigating to Customization > Custom Links. Each link is associated with a particular NetBox object type (site, device, prefix, etc.) and will be displayed on relevant views. Each link has display text and a URL, and data from the NetBox item being viewed can be included in the link using [Jinja2 template code](https://jinja2docs.readthedocs.io/en/stable/) through the variable `obj`, and custom fields through `obj.cf`. For example, you might define a link like this: @@ -32,6 +32,10 @@ The following context data is available within the template when rendering a cus | `user` | The current user (if authenticated) | | `perms` | The [permissions](https://docs.djangoproject.com/en/stable/topics/auth/default/#permissions) assigned to the user | +While most of the context variables listed above will have consistent attributes, the object will be an instance of the specific object being viewed when the link is rendered. Different models have different fields and properties, so you may need to some research to determine the attributes available for use within your template for a specific object type. + +Checking the REST API representation of an object is generally a convenient way to determine what attributes are available. You can also reference the NetBox source code directly for a comprehensive list. + ## Conditional Rendering Only links which render with non-empty text are included on the page. You can employ conditional Jinja2 logic to control the conditions under which a link gets rendered. From 2d09a40663039bdd33c427f65b945272d10eafd3 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 30 Mar 2022 15:04:13 -0400 Subject: [PATCH 19/94] Closes #8601: Include group when displaying tenant assigned to cluster --- netbox/templates/virtualization/cluster.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/netbox/templates/virtualization/cluster.html b/netbox/templates/virtualization/cluster.html index b7af89bb2..b05ba3f8f 100644 --- a/netbox/templates/virtualization/cluster.html +++ b/netbox/templates/virtualization/cluster.html @@ -33,6 +33,9 @@ Tenant {% if object.tenant %} + {% if object.tenant.group %} + {{ object.tenant.group }} / + {% endif %} {{ object.tenant }} {% else %} None From 91e8f57afb7fd257533ed30e30c86ed3cd87c111 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 30 Mar 2022 15:39:28 -0400 Subject: [PATCH 20/94] Change log & cleanup for #8163, #8866 --- docs/release-notes/version-3.1.md | 5 +++++ netbox/project-static/dist/netbox.js | Bin 375655 -> 375623 bytes netbox/project-static/dist/netbox.js.map | Bin 344977 -> 344951 bytes 3 files changed, 5 insertions(+) diff --git a/docs/release-notes/version-3.1.md b/docs/release-notes/version-3.1.md index 303a05cae..5092d18ed 100644 --- a/docs/release-notes/version-3.1.md +++ b/docs/release-notes/version-3.1.md @@ -4,10 +4,15 @@ ### Enhancements +* [#8163](https://github.com/netbox-community/netbox/issues/8163) - Show bridge interface members under interface view * [#8785](https://github.com/netbox-community/netbox/issues/8785) - Permit wildcard values in IP address DNS names * [#8830](https://github.com/netbox-community/netbox/issues/8830) - Add Checkpoint ClusterXL protocol for FHRP groups * [#8974](https://github.com/netbox-community/netbox/issues/8974) - Use monospace font for text areas in config revision form +### Bug Fixes + +* [#8866](https://github.com/netbox-community/netbox/issues/8866) - Prevent exception when searching for a rack position with no rack specified under device edit view + --- ## v3.1.10 (2022-03-25) diff --git a/netbox/project-static/dist/netbox.js b/netbox/project-static/dist/netbox.js index be807c2deebe794c033929da381b3550b567e34e..136135ce76f1a844cd776f6f357dfe783c819959 100644 GIT binary patch delta 42 ycmaFF7M3lnwQF7M3lnwQ&N;`FX|pIjMR%`RN*od73)YYvWke#B`8_^YSz` Vt#eXK6sE6DT||{qvup-R!!DKM^AI-t&OaqESv=uPF2o2{*Hy) S@3XM_u``x!*W+PLHU|J+^Ac15 delta 88 zcmey~COWZQw4sHug{g(Pg=Gq>DPN$YW1xF8YMtb>s7cJ$0~ i+M3Q9%EDPv;Z)_U Date: Wed, 30 Mar 2022 15:51:12 -0400 Subject: [PATCH 21/94] Closes #8790: Include site and prefixes columns in VLAN group VLANs table --- docs/release-notes/version-3.1.md | 1 + netbox/ipam/views.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.1.md b/docs/release-notes/version-3.1.md index 5092d18ed..7e8e93632 100644 --- a/docs/release-notes/version-3.1.md +++ b/docs/release-notes/version-3.1.md @@ -6,6 +6,7 @@ * [#8163](https://github.com/netbox-community/netbox/issues/8163) - Show bridge interface members under interface view * [#8785](https://github.com/netbox-community/netbox/issues/8785) - Permit wildcard values in IP address DNS names +* [#8790](https://github.com/netbox-community/netbox/issues/8790) - Include site and prefixes columns in VLAN group VLANs table * [#8830](https://github.com/netbox-community/netbox/issues/8830) - Add Checkpoint ClusterXL protocol for FHRP groups * [#8974](https://github.com/netbox-community/netbox/issues/8974) - Use monospace font for text areas in config revision form diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index aab9a6249..e32cf4d96 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -795,7 +795,7 @@ class VLANGroupView(generic.ObjectView): vlans_count = vlans.count() vlans = add_available_vlans(vlans, vlan_group=instance) - vlans_table = tables.VLANTable(vlans, exclude=('site', 'group', 'prefixes')) + vlans_table = tables.VLANTable(vlans, exclude=('group',)) if request.user.has_perm('ipam.change_vlan') or request.user.has_perm('ipam.delete_vlan'): vlans_table.columns.show('pk') paginate_table(vlans_table, request) From cdacd2a95158be9c7451dfeacbb37b01ee078f35 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 30 Mar 2022 16:19:12 -0400 Subject: [PATCH 22/94] Closes #8593: Add link field to contact model --- docs/release-notes/version-3.2.md | 3 +++ netbox/templates/tenancy/contact.html | 10 ++++++++++ netbox/tenancy/api/serializers.py | 2 +- netbox/tenancy/filtersets.py | 3 ++- netbox/tenancy/forms/bulk_edit.py | 7 +++++-- netbox/tenancy/forms/bulk_import.py | 2 +- netbox/tenancy/forms/models.py | 8 +++----- netbox/tenancy/migrations/0007_contact_link.py | 17 +++++++++++++++++ netbox/tenancy/models/contacts.py | 3 +++ netbox/tenancy/tables/contacts.py | 2 +- 10 files changed, 46 insertions(+), 11 deletions(-) create mode 100644 netbox/tenancy/migrations/0007_contact_link.py diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index 2b85e6eda..c120ce931 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -143,6 +143,7 @@ Where it is desired to limit the range of available VLANs within a group, users * [#8307](https://github.com/netbox-community/netbox/issues/8307) - Add `data_type` indicator to REST API serializer for custom fields * [#8463](https://github.com/netbox-community/netbox/issues/8463) - Change the `created` field on all change-logged models from date to datetime * [#8572](https://github.com/netbox-community/netbox/issues/8572) - Add a `pre_run()` method for reports +* [#8593](https://github.com/netbox-community/netbox/issues/8593) - Add a `link` field for contacts * [#8649](https://github.com/netbox-community/netbox/issues/8649) - Enable customization of configuration module using `NETBOX_CONFIGURATION` environment variable ### Bug Fixes (From Beta2) @@ -205,5 +206,7 @@ Where it is desired to limit the range of available VLANs within a group, users * ipam.VLANGroup * Added the `/availables-vlans/` endpoint * Added the `min_vid` and `max_vid` fields +* tenancy.Contact + * Added the `link` field * virtualization.VMInterface * Added `vrf` field diff --git a/netbox/templates/tenancy/contact.html b/netbox/templates/tenancy/contact.html index 3b97a5a20..f55e87895 100644 --- a/netbox/templates/tenancy/contact.html +++ b/netbox/templates/tenancy/contact.html @@ -53,6 +53,16 @@ Address {{ object.address|linebreaksbr|placeholder }} + + Link + + {% if object.link %} + {{ object.link }} + {% else %} + {{ ''|placeholder }} + {% endif %} + + Assignments {{ assignment_count }} diff --git a/netbox/tenancy/api/serializers.py b/netbox/tenancy/api/serializers.py index 21a75a6bf..8749dc63f 100644 --- a/netbox/tenancy/api/serializers.py +++ b/netbox/tenancy/api/serializers.py @@ -84,7 +84,7 @@ class ContactSerializer(NetBoxModelSerializer): class Meta: model = Contact fields = [ - 'id', 'url', 'display', 'group', 'name', 'title', 'phone', 'email', 'address', 'comments', 'tags', + 'id', 'url', 'display', 'group', 'name', 'title', 'phone', 'email', 'address', 'link', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', ] diff --git a/netbox/tenancy/filtersets.py b/netbox/tenancy/filtersets.py index 03f3fdf6d..8ca4ae29c 100644 --- a/netbox/tenancy/filtersets.py +++ b/netbox/tenancy/filtersets.py @@ -63,7 +63,7 @@ class ContactFilterSet(NetBoxModelFilterSet): class Meta: model = Contact - fields = ['id', 'name', 'title', 'phone', 'email', 'address'] + fields = ['id', 'name', 'title', 'phone', 'email', 'address', 'link'] def search(self, queryset, name, value): if not value.strip(): @@ -74,6 +74,7 @@ class ContactFilterSet(NetBoxModelFilterSet): Q(phone__icontains=value) | Q(email__icontains=value) | Q(address__icontains=value) | + Q(link__icontains=value) | Q(comments__icontains=value) ) diff --git a/netbox/tenancy/forms/bulk_edit.py b/netbox/tenancy/forms/bulk_edit.py index 270e2b4a5..4c1f03757 100644 --- a/netbox/tenancy/forms/bulk_edit.py +++ b/netbox/tenancy/forms/bulk_edit.py @@ -98,9 +98,12 @@ class ContactBulkEditForm(NetBoxModelBulkEditForm): max_length=200, required=False ) + link = forms.URLField( + required=False + ) model = Contact fieldsets = ( - (None, ('group', 'title', 'phone', 'email', 'address')), + (None, ('group', 'title', 'phone', 'email', 'address', 'link')), ) - nullable_fields = ('group', 'title', 'phone', 'email', 'address', 'comments') + nullable_fields = ('group', 'title', 'phone', 'email', 'address', 'link', 'comments') diff --git a/netbox/tenancy/forms/bulk_import.py b/netbox/tenancy/forms/bulk_import.py index 409590c28..d617a27b5 100644 --- a/netbox/tenancy/forms/bulk_import.py +++ b/netbox/tenancy/forms/bulk_import.py @@ -79,4 +79,4 @@ class ContactCSVForm(NetBoxModelCSVForm): class Meta: model = Contact - fields = ('name', 'title', 'phone', 'email', 'address', 'group', 'comments') + fields = ('name', 'title', 'phone', 'email', 'address', 'link', 'group', 'comments') diff --git a/netbox/tenancy/forms/models.py b/netbox/tenancy/forms/models.py index 35b631d43..021e36a5b 100644 --- a/netbox/tenancy/forms/models.py +++ b/netbox/tenancy/forms/models.py @@ -1,11 +1,9 @@ from django import forms -from extras.models import Tag from netbox.forms import NetBoxModelForm from tenancy.models import * from utilities.forms import ( - BootstrapMixin, CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SlugField, SmallTextarea, - StaticSelect, + BootstrapMixin, CommentField, DynamicModelChoiceField, SlugField, SmallTextarea, StaticSelect, ) __all__ = ( @@ -87,13 +85,13 @@ class ContactForm(NetBoxModelForm): comments = CommentField() fieldsets = ( - ('Contact', ('group', 'name', 'title', 'phone', 'email', 'address', 'tags')), + ('Contact', ('group', 'name', 'title', 'phone', 'email', 'address', 'link', 'tags')), ) class Meta: model = Contact fields = ( - 'group', 'name', 'title', 'phone', 'email', 'address', 'comments', 'tags', + 'group', 'name', 'title', 'phone', 'email', 'address', 'link', 'comments', 'tags', ) widgets = { 'address': SmallTextarea(attrs={'rows': 3}), diff --git a/netbox/tenancy/migrations/0007_contact_link.py b/netbox/tenancy/migrations/0007_contact_link.py new file mode 100644 index 000000000..43b7495e5 --- /dev/null +++ b/netbox/tenancy/migrations/0007_contact_link.py @@ -0,0 +1,17 @@ +from django.db import migrations, models +import utilities.validators + + +class Migration(migrations.Migration): + + dependencies = [ + ('tenancy', '0006_created_datetimefield'), + ] + + operations = [ + migrations.AddField( + model_name='contact', + name='link', + field=models.URLField(blank=True), + ), + ] diff --git a/netbox/tenancy/models/contacts.py b/netbox/tenancy/models/contacts.py index 50b75ada7..75ec9f69c 100644 --- a/netbox/tenancy/models/contacts.py +++ b/netbox/tenancy/models/contacts.py @@ -105,6 +105,9 @@ class Contact(NetBoxModel): max_length=200, blank=True ) + link = models.URLField( + blank=True + ) comments = models.TextField( blank=True ) diff --git a/netbox/tenancy/tables/contacts.py b/netbox/tenancy/tables/contacts.py index cc37efd44..17abc5a5b 100644 --- a/netbox/tenancy/tables/contacts.py +++ b/netbox/tenancy/tables/contacts.py @@ -65,7 +65,7 @@ class ContactTable(NetBoxTable): class Meta(NetBoxTable.Meta): model = Contact fields = ( - 'pk', 'name', 'group', 'title', 'phone', 'email', 'address', 'comments', 'assignment_count', 'tags', + 'pk', 'name', 'group', 'title', 'phone', 'email', 'address', 'link', 'comments', 'assignment_count', 'tags', 'created', 'last_updated', ) default_columns = ('pk', 'name', 'group', 'assignment_count', 'title', 'phone', 'email') From bddc35bbc75e78e9fb0cf9c77c9465a2e519d30e Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 30 Mar 2022 17:17:36 -0400 Subject: [PATCH 23/94] Closes #8496: Enable assigning multiple ASNs to a provider --- docs/release-notes/version-3.2.md | 7 +++- netbox/circuits/api/serializers.py | 14 ++++++- netbox/circuits/api/views.py | 2 +- netbox/circuits/filtersets.py | 6 +++ netbox/circuits/forms/bulk_edit.py | 18 +++++++-- netbox/circuits/forms/filtersets.py | 8 +++- netbox/circuits/forms/models.py | 12 ++++-- .../circuits/migrations/0035_provider_asns.py | 19 +++++++++ netbox/circuits/models/providers.py | 5 +++ netbox/circuits/tables/providers.py | 14 ++++++- netbox/circuits/tests/test_api.py | 39 ++++++++++++------- netbox/circuits/tests/test_filtersets.py | 19 ++++++++- netbox/circuits/tests/test_views.py | 16 +++++++- netbox/dcim/api/serializers.py | 8 ++-- netbox/dcim/forms/models.py | 1 - netbox/dcim/tables/sites.py | 8 ++-- netbox/ipam/api/serializers.py | 5 ++- netbox/ipam/api/views.py | 6 ++- netbox/ipam/tables/ip.py | 11 ++++-- netbox/ipam/views.py | 13 ++++++- netbox/templates/circuits/provider.html | 25 +++++++++--- netbox/templates/ipam/asn.html | 19 ++++++++- 22 files changed, 222 insertions(+), 53 deletions(-) create mode 100644 netbox/circuits/migrations/0035_provider_asns.py diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index c120ce931..d420b8108 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -142,6 +142,7 @@ Where it is desired to limit the range of available VLANs within a group, users * [#8296](https://github.com/netbox-community/netbox/issues/8296) - Allow disabling custom links * [#8307](https://github.com/netbox-community/netbox/issues/8307) - Add `data_type` indicator to REST API serializer for custom fields * [#8463](https://github.com/netbox-community/netbox/issues/8463) - Change the `created` field on all change-logged models from date to datetime +* [#8496](https://github.com/netbox-community/netbox/issues/8496) - Enable assigning multiple ASNs to a provider * [#8572](https://github.com/netbox-community/netbox/issues/8572) - Add a `pre_run()` method for reports * [#8593](https://github.com/netbox-community/netbox/issues/8593) - Add a `link` field for contacts * [#8649](https://github.com/netbox-community/netbox/issues/8649) - Enable customization of configuration module using `NETBOX_CONFIGURATION` environment variable @@ -176,6 +177,8 @@ Where it is desired to limit the range of available VLANs within a group, users * `/api/dcim/module-types/` * `/api/ipam/service-templates/` * `/api/ipam/vlan-groups//available-vlans/` +* circuits.Provider + * Added `asns` field * circuits.ProviderNetwork * Added `service_id` field * dcim.ConsolePort @@ -203,10 +206,12 @@ Where it is desired to limit the range of available VLANs within a group, users * Added `data_type` and `object_type` fields * extras.CustomLink * Added `enabled` field +* ipam.ASN + * Added `provider_count` field * ipam.VLANGroup * Added the `/availables-vlans/` endpoint * Added the `min_vid` and `max_vid` fields * tenancy.Contact - * Added the `link` field + * Added `link` field * virtualization.VMInterface * Added `vrf` field diff --git a/netbox/circuits/api/serializers.py b/netbox/circuits/api/serializers.py index 539ff9466..19570f067 100644 --- a/netbox/circuits/api/serializers.py +++ b/netbox/circuits/api/serializers.py @@ -4,7 +4,9 @@ from circuits.choices import CircuitStatusChoices from circuits.models import * from dcim.api.nested_serializers import NestedCableSerializer, NestedSiteSerializer from dcim.api.serializers import LinkTerminationSerializer -from netbox.api import ChoiceField +from ipam.models import ASN +from ipam.api.nested_serializers import NestedASNSerializer +from netbox.api import ChoiceField, SerializedPKRelatedField from netbox.api.serializers import NetBoxModelSerializer, ValidatedModelSerializer, WritableNestedSerializer from tenancy.api.nested_serializers import NestedTenantSerializer from .nested_serializers import * @@ -16,13 +18,21 @@ from .nested_serializers import * class ProviderSerializer(NetBoxModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='circuits-api:provider-detail') + asns = SerializedPKRelatedField( + queryset=ASN.objects.all(), + serializer=NestedASNSerializer, + required=False, + many=True + ) + + # Related object counts circuit_count = serializers.IntegerField(read_only=True) class Meta: model = Provider fields = [ 'id', 'url', 'display', 'name', 'slug', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', - 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'circuit_count', + 'comments', 'asns', 'tags', 'custom_fields', 'created', 'last_updated', 'circuit_count', ] diff --git a/netbox/circuits/api/views.py b/netbox/circuits/api/views.py index 99687fe9d..3573c05e3 100644 --- a/netbox/circuits/api/views.py +++ b/netbox/circuits/api/views.py @@ -21,7 +21,7 @@ class CircuitsRootView(APIRootView): # class ProviderViewSet(NetBoxModelViewSet): - queryset = Provider.objects.prefetch_related('tags').annotate( + queryset = Provider.objects.prefetch_related('asns', 'tags').annotate( circuit_count=count_related(Circuit, 'provider') ) serializer_class = serializers.ProviderSerializer diff --git a/netbox/circuits/filtersets.py b/netbox/circuits/filtersets.py index 9bf2bb439..b7fa100a8 100644 --- a/netbox/circuits/filtersets.py +++ b/netbox/circuits/filtersets.py @@ -3,6 +3,7 @@ from django.db.models import Q from dcim.filtersets import CableTerminationFilterSet from dcim.models import Region, Site, SiteGroup +from ipam.models import ASN from netbox.filtersets import ChangeLoggedModelFilterSet, NetBoxModelFilterSet, OrganizationalModelFilterSet from tenancy.filtersets import ContactModelFilterSet, TenancyFilterSet from utilities.filters import TreeNodeMultipleChoiceFilter @@ -56,6 +57,11 @@ class ProviderFilterSet(NetBoxModelFilterSet, ContactModelFilterSet): to_field_name='slug', label='Site (slug)', ) + asn_id = django_filters.ModelMultipleChoiceFilter( + field_name='asns', + queryset=ASN.objects.all(), + label='ASN (ID)', + ) class Meta: model = Provider diff --git a/netbox/circuits/forms/bulk_edit.py b/netbox/circuits/forms/bulk_edit.py index 8fc76e940..6e283219a 100644 --- a/netbox/circuits/forms/bulk_edit.py +++ b/netbox/circuits/forms/bulk_edit.py @@ -1,10 +1,15 @@ from django import forms +from django.utils.translation import gettext as _ from circuits.choices import CircuitStatusChoices from circuits.models import * +from ipam.models import ASN from netbox.forms import NetBoxModelBulkEditForm from tenancy.models import Tenant -from utilities.forms import add_blank_choice, CommentField, DynamicModelChoiceField, SmallTextarea, StaticSelect +from utilities.forms import ( + add_blank_choice, CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SmallTextarea, + StaticSelect, +) __all__ = ( 'CircuitBulkEditForm', @@ -17,7 +22,12 @@ __all__ = ( class ProviderBulkEditForm(NetBoxModelBulkEditForm): asn = forms.IntegerField( required=False, - label='ASN' + label='ASN (legacy)' + ) + asns = DynamicModelMultipleChoiceField( + queryset=ASN.objects.all(), + label=_('ASNs'), + required=False ) account = forms.CharField( max_length=30, @@ -45,10 +55,10 @@ class ProviderBulkEditForm(NetBoxModelBulkEditForm): model = Provider fieldsets = ( - (None, ('asn', 'account', 'portal_url', 'noc_contact', 'admin_contact')), + (None, ('asn', 'asns', 'account', 'portal_url', 'noc_contact', 'admin_contact')), ) nullable_fields = ( - 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments', + 'asn', 'asns', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments', ) diff --git a/netbox/circuits/forms/filtersets.py b/netbox/circuits/forms/filtersets.py index 4f0d99895..ca3b003b9 100644 --- a/netbox/circuits/forms/filtersets.py +++ b/netbox/circuits/forms/filtersets.py @@ -4,6 +4,7 @@ from django.utils.translation import gettext as _ from circuits.choices import CircuitStatusChoices from circuits.models import * from dcim.models import Region, Site, SiteGroup +from ipam.models import ASN from netbox.forms import NetBoxModelFilterSetForm from tenancy.forms import TenancyFilterForm, ContactModelFilterForm from utilities.forms import DynamicModelMultipleChoiceField, MultipleChoiceField, TagFilterField @@ -45,7 +46,12 @@ class ProviderFilterForm(ContactModelFilterForm, NetBoxModelFilterSetForm): ) asn = forms.IntegerField( required=False, - label=_('ASN') + label=_('ASN (legacy)') + ) + asn_id = DynamicModelMultipleChoiceField( + queryset=ASN.objects.all(), + required=False, + label=_('ASNs') ) tag = TagFilterField(model) diff --git a/netbox/circuits/forms/models.py b/netbox/circuits/forms/models.py index c7d7f8438..8fd5fb92d 100644 --- a/netbox/circuits/forms/models.py +++ b/netbox/circuits/forms/models.py @@ -1,8 +1,9 @@ from django import forms +from django.utils.translation import gettext as _ from circuits.models import * from dcim.models import Region, Site, SiteGroup -from extras.models import Tag +from ipam.models import ASN from netbox.forms import NetBoxModelForm from tenancy.forms import TenancyForm from utilities.forms import ( @@ -21,17 +22,22 @@ __all__ = ( class ProviderForm(NetBoxModelForm): slug = SlugField() + asns = DynamicModelMultipleChoiceField( + queryset=ASN.objects.all(), + label=_('ASNs'), + required=False + ) comments = CommentField() fieldsets = ( - ('Provider', ('name', 'slug', 'asn', 'tags')), + ('Provider', ('name', 'slug', 'asn', 'asns', 'tags')), ('Support Info', ('account', 'portal_url', 'noc_contact', 'admin_contact')), ) class Meta: model = Provider fields = [ - 'name', 'slug', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'comments', 'tags', + 'name', 'slug', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'asns', 'comments', 'tags', ] widgets = { 'noc_contact': SmallTextarea( diff --git a/netbox/circuits/migrations/0035_provider_asns.py b/netbox/circuits/migrations/0035_provider_asns.py new file mode 100644 index 000000000..afb0da4d6 --- /dev/null +++ b/netbox/circuits/migrations/0035_provider_asns.py @@ -0,0 +1,19 @@ +# Generated by Django 4.0.3 on 2022-03-30 20:27 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ipam', '0057_created_datetimefield'), + ('circuits', '0034_created_datetimefield'), + ] + + operations = [ + migrations.AddField( + model_name='provider', + name='asns', + field=models.ManyToManyField(blank=True, related_name='providers', to='ipam.asn'), + ), + ] diff --git a/netbox/circuits/models/providers.py b/netbox/circuits/models/providers.py index 9cf4bf5c1..4211a54a6 100644 --- a/netbox/circuits/models/providers.py +++ b/netbox/circuits/models/providers.py @@ -30,6 +30,11 @@ class Provider(NetBoxModel): verbose_name='ASN', help_text='32-bit autonomous system number' ) + asns = models.ManyToManyField( + to='ipam.ASN', + related_name='providers', + blank=True + ) account = models.CharField( max_length=30, blank=True, diff --git a/netbox/circuits/tables/providers.py b/netbox/circuits/tables/providers.py index d5b4329fb..c50610398 100644 --- a/netbox/circuits/tables/providers.py +++ b/netbox/circuits/tables/providers.py @@ -14,6 +14,16 @@ class ProviderTable(NetBoxTable): name = tables.Column( linkify=True ) + asns = tables.ManyToManyColumn( + linkify_item=True, + verbose_name='ASNs' + ) + asn_count = columns.LinkedCountColumn( + accessor=tables.A('asns__count'), + viewname='ipam:asn_list', + url_params={'provider_id': 'pk'}, + verbose_name='ASN Count' + ) circuit_count = tables.Column( accessor=Accessor('count_circuits'), verbose_name='Circuits' @@ -29,8 +39,8 @@ class ProviderTable(NetBoxTable): class Meta(NetBoxTable.Meta): model = Provider fields = ( - 'pk', 'id', 'name', 'asn', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'circuit_count', - 'comments', 'contacts', 'tags', 'created', 'last_updated', + 'pk', 'id', 'name', 'asn', 'asns', 'account', 'portal_url', 'noc_contact', 'admin_contact', 'asn_count', + 'circuit_count', 'comments', 'contacts', 'tags', 'created', 'last_updated', ) default_columns = ('pk', 'name', 'asn', 'account', 'circuit_count') diff --git a/netbox/circuits/tests/test_api.py b/netbox/circuits/tests/test_api.py index 830c7d9ca..02b489ac4 100644 --- a/netbox/circuits/tests/test_api.py +++ b/netbox/circuits/tests/test_api.py @@ -3,6 +3,7 @@ from django.urls import reverse from circuits.choices import * from circuits.models import * from dcim.models import Site +from ipam.models import ASN, RIR from utilities.testing import APITestCase, APIViewTestCases @@ -18,20 +19,6 @@ class AppTest(APITestCase): class ProviderTest(APIViewTestCases.APIViewTestCase): model = Provider brief_fields = ['circuit_count', 'display', 'id', 'name', 'slug', 'url'] - create_data = [ - { - 'name': 'Provider 4', - 'slug': 'provider-4', - }, - { - 'name': 'Provider 5', - 'slug': 'provider-5', - }, - { - 'name': 'Provider 6', - 'slug': 'provider-6', - }, - ] bulk_update_data = { 'asn': 1234, } @@ -39,6 +26,12 @@ class ProviderTest(APIViewTestCases.APIViewTestCase): @classmethod def setUpTestData(cls): + rir = RIR.objects.create(name='RFC 6996', is_private=True) + asns = [ + ASN(asn=65000 + i, rir=rir) for i in range(8) + ] + ASN.objects.bulk_create(asns) + providers = ( Provider(name='Provider 1', slug='provider-1'), Provider(name='Provider 2', slug='provider-2'), @@ -46,6 +39,24 @@ class ProviderTest(APIViewTestCases.APIViewTestCase): ) Provider.objects.bulk_create(providers) + cls.create_data = [ + { + 'name': 'Provider 4', + 'slug': 'provider-4', + 'asns': [asns[0].pk, asns[1].pk], + }, + { + 'name': 'Provider 5', + 'slug': 'provider-5', + 'asns': [asns[2].pk, asns[3].pk], + }, + { + 'name': 'Provider 6', + 'slug': 'provider-6', + 'asns': [asns[4].pk, asns[5].pk], + }, + ] + class CircuitTypeTest(APIViewTestCases.APIViewTestCase): model = CircuitType diff --git a/netbox/circuits/tests/test_filtersets.py b/netbox/circuits/tests/test_filtersets.py index 20416c4e6..205236712 100644 --- a/netbox/circuits/tests/test_filtersets.py +++ b/netbox/circuits/tests/test_filtersets.py @@ -4,6 +4,7 @@ from circuits.choices import * from circuits.filtersets import * from circuits.models import * from dcim.models import Cable, Region, Site, SiteGroup +from ipam.models import ASN, RIR from tenancy.models import Tenant, TenantGroup from utilities.testing import ChangeLoggedFilterSetTests @@ -15,6 +16,14 @@ class ProviderTestCase(TestCase, ChangeLoggedFilterSetTests): @classmethod def setUpTestData(cls): + rir = RIR.objects.create(name='RFC 6996', is_private=True) + asns = ( + ASN(asn=64512, rir=rir), + ASN(asn=64513, rir=rir), + ASN(asn=64514, rir=rir), + ) + ASN.objects.bulk_create(asns) + providers = ( Provider(name='Provider 1', slug='provider-1', asn=65001, account='1234'), Provider(name='Provider 2', slug='provider-2', asn=65002, account='2345'), @@ -23,6 +32,9 @@ class ProviderTestCase(TestCase, ChangeLoggedFilterSetTests): Provider(name='Provider 5', slug='provider-5', asn=65005, account='5678'), ) Provider.objects.bulk_create(providers) + providers[0].asns.set([asns[0]]) + providers[1].asns.set([asns[1]]) + providers[2].asns.set([asns[2]]) regions = ( Region(name='Test Region 1', slug='test-region-1'), @@ -70,10 +82,15 @@ class ProviderTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'slug': ['provider-1', 'provider-2']} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - def test_asn(self): + def test_asn(self): # Legacy field params = {'asn': ['65001', '65002']} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + def test_asn_id(self): # ASN object assignment + asns = ASN.objects.all()[:2] + params = {'asn_id': [asns[0].pk, asns[1].pk]} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + def test_account(self): params = {'account': ['1234', '2345']} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) diff --git a/netbox/circuits/tests/test_views.py b/netbox/circuits/tests/test_views.py index d8ad27d72..17c846c86 100644 --- a/netbox/circuits/tests/test_views.py +++ b/netbox/circuits/tests/test_views.py @@ -6,6 +6,7 @@ from django.urls import reverse from circuits.choices import * from circuits.models import * from dcim.models import Cable, Interface, Site +from ipam.models import ASN, RIR from utilities.testing import ViewTestCases, create_tags, create_test_device @@ -15,11 +16,21 @@ class ProviderTestCase(ViewTestCases.PrimaryObjectViewTestCase): @classmethod def setUpTestData(cls): - Provider.objects.bulk_create([ + rir = RIR.objects.create(name='RFC 6996', is_private=True) + asns = [ + ASN(asn=65000 + i, rir=rir) for i in range(8) + ] + ASN.objects.bulk_create(asns) + + providers = ( Provider(name='Provider 1', slug='provider-1', asn=65001), Provider(name='Provider 2', slug='provider-2', asn=65002), Provider(name='Provider 3', slug='provider-3', asn=65003), - ]) + ) + Provider.objects.bulk_create(providers) + providers[0].asns.set([asns[0], asns[1]]) + providers[1].asns.set([asns[2], asns[3]]) + providers[2].asns.set([asns[4], asns[5]]) tags = create_tags('Alpha', 'Bravo', 'Charlie') @@ -27,6 +38,7 @@ class ProviderTestCase(ViewTestCases.PrimaryObjectViewTestCase): 'name': 'Provider X', 'slug': 'provider-x', 'asn': 65123, + 'asns': [asns[6].pk, asns[7].pk], 'account': '1234', 'portal_url': 'http://example.com/portal', 'noc_contact': 'noc@example.com', diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index d6f8b347c..813c946a3 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -134,10 +134,10 @@ class SiteSerializer(NetBoxModelSerializer): class Meta: model = Site fields = [ - 'id', 'url', 'display', 'name', 'slug', 'status', 'region', 'group', 'tenant', 'facility', 'asns', - 'time_zone', 'description', 'physical_address', 'shipping_address', 'latitude', 'longitude', 'comments', - 'tags', 'custom_fields', 'created', 'last_updated', 'circuit_count', 'device_count', 'prefix_count', - 'rack_count', 'virtualmachine_count', 'vlan_count', + 'id', 'url', 'display', 'name', 'slug', 'status', 'region', 'group', 'tenant', 'facility', 'time_zone', + 'description', 'physical_address', 'shipping_address', 'latitude', 'longitude', 'comments', 'asns', 'tags', + 'custom_fields', 'created', 'last_updated', 'circuit_count', 'device_count', 'prefix_count', 'rack_count', + 'virtualmachine_count', 'vlan_count', ] diff --git a/netbox/dcim/forms/models.py b/netbox/dcim/forms/models.py index 6054ee7bf..57e2fa820 100644 --- a/netbox/dcim/forms/models.py +++ b/netbox/dcim/forms/models.py @@ -7,7 +7,6 @@ from timezone_field import TimeZoneFormField from dcim.choices import * from dcim.constants import * from dcim.models import * -from extras.models import Tag from ipam.models import ASN, IPAddress, VLAN, VLANGroup, VRF from netbox.forms import NetBoxModelForm from tenancy.forms import TenancyForm diff --git a/netbox/dcim/tables/sites.py b/netbox/dcim/tables/sites.py index d4d355474..84522480f 100644 --- a/netbox/dcim/tables/sites.py +++ b/netbox/dcim/tables/sites.py @@ -86,16 +86,16 @@ class SiteTable(NetBoxTable): group = tables.Column( linkify=True ) + asns = tables.ManyToManyColumn( + linkify_item=True, + verbose_name='ASNs' + ) asn_count = columns.LinkedCountColumn( accessor=tables.A('asns__count'), viewname='ipam:asn_list', url_params={'site_id': 'pk'}, verbose_name='ASN Count' ) - asns = tables.ManyToManyColumn( - linkify_item=True, - verbose_name='ASNs' - ) tenant = TenantColumn() comments = columns.MarkdownColumn() contacts = tables.ManyToManyColumn( diff --git a/netbox/ipam/api/serializers.py b/netbox/ipam/api/serializers.py index c26575f1f..3fa1bcc7e 100644 --- a/netbox/ipam/api/serializers.py +++ b/netbox/ipam/api/serializers.py @@ -24,12 +24,13 @@ class ASNSerializer(NetBoxModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='ipam-api:asn-detail') tenant = NestedTenantSerializer(required=False, allow_null=True) site_count = serializers.IntegerField(read_only=True) + provider_count = serializers.IntegerField(read_only=True) class Meta: model = ASN fields = [ - 'id', 'url', 'display', 'asn', 'site_count', 'rir', 'tenant', 'description', 'tags', 'custom_fields', - 'created', 'last_updated', + 'id', 'url', 'display', 'asn', 'rir', 'tenant', 'description', 'site_count', 'provider_count', 'tags', + 'custom_fields', 'created', 'last_updated', ] diff --git a/netbox/ipam/api/views.py b/netbox/ipam/api/views.py index c09cffa05..dcddec580 100644 --- a/netbox/ipam/api/views.py +++ b/netbox/ipam/api/views.py @@ -8,6 +8,7 @@ from rest_framework.response import Response from rest_framework.routers import APIRootView from rest_framework.views import APIView +from circuits.models import Provider from dcim.models import Site from ipam import filtersets from ipam.models import * @@ -32,7 +33,10 @@ class IPAMRootView(APIRootView): # class ASNViewSet(NetBoxModelViewSet): - queryset = ASN.objects.prefetch_related('tenant', 'rir').annotate(site_count=count_related(Site, 'asns')) + queryset = ASN.objects.prefetch_related('tenant', 'rir').annotate( + site_count=count_related(Site, 'asns'), + provider_count=count_related(Provider, 'asns') + ) serializer_class = serializers.ASNSerializer filterset_class = filtersets.ASNFilterSet diff --git a/netbox/ipam/tables/ip.py b/netbox/ipam/tables/ip.py index ac25b113b..244bcee8e 100644 --- a/netbox/ipam/tables/ip.py +++ b/netbox/ipam/tables/ip.py @@ -113,6 +113,11 @@ class ASNTable(NetBoxTable): url_params={'asn_id': 'pk'}, verbose_name='Site Count' ) + provider_count = columns.LinkedCountColumn( + viewname='circuits:provider_list', + url_params={'asn_id': 'pk'}, + verbose_name='Provider Count' + ) sites = tables.ManyToManyColumn( linkify_item=True, verbose_name='Sites' @@ -125,10 +130,10 @@ class ASNTable(NetBoxTable): class Meta(NetBoxTable.Meta): model = ASN fields = ( - 'pk', 'asn', 'asn_asdot', 'rir', 'site_count', 'tenant', 'description', 'sites', 'tags', 'created', - 'last_updated', 'actions', + 'pk', 'asn', 'asn_asdot', 'rir', 'site_count', 'provider_count', 'tenant', 'description', 'sites', 'tags', + 'created', 'last_updated', 'actions', ) - default_columns = ('pk', 'asn', 'rir', 'site_count', 'sites', 'description', 'tenant') + default_columns = ('pk', 'asn', 'rir', 'site_count', 'provider_count', 'sites', 'description', 'tenant') # diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index 9faa35ac6..336a6ea72 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -4,6 +4,8 @@ from django.db.models.expressions import RawSQL from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse +from circuits.models import Provider +from circuits.tables import ProviderTable from dcim.filtersets import InterfaceFilterSet from dcim.models import Interface, Site from dcim.tables import SiteTable @@ -206,6 +208,7 @@ class RIRBulkDeleteView(generic.BulkDeleteView): class ASNListView(generic.ObjectListView): queryset = ASN.objects.annotate( site_count=count_related(Site, 'asns'), + provider_count=count_related(Provider, 'asns') ) filterset = filtersets.ASNFilterSet filterset_form = forms.ASNFilterForm @@ -216,13 +219,21 @@ class ASNView(generic.ObjectView): queryset = ASN.objects.all() def get_extra_context(self, request, instance): + # Gather assigned Sites sites = instance.sites.restrict(request.user, 'view') sites_table = SiteTable(sites) sites_table.configure(request) + # Gather assigned Providers + providers = instance.providers.restrict(request.user, 'view') + providers_table = ProviderTable(providers) + providers_table.configure(request) + return { 'sites_table': sites_table, - 'sites_count': sites.count() + 'sites_count': sites.count(), + 'providers_table': providers_table, + 'providers_count': providers.count(), } diff --git a/netbox/templates/circuits/provider.html b/netbox/templates/circuits/provider.html index 3fd275c7c..1bf63f2d5 100644 --- a/netbox/templates/circuits/provider.html +++ b/netbox/templates/circuits/provider.html @@ -16,14 +16,29 @@
-
- Provider -
+
Provider
- - + + + + + + diff --git a/netbox/templates/ipam/asn.html b/netbox/templates/ipam/asn.html index 6c092f598..7afe981e6 100644 --- a/netbox/templates/ipam/asn.html +++ b/netbox/templates/ipam/asn.html @@ -45,7 +45,17 @@ {% if sites_count %} {{ sites_count }} {% else %} - {{ sites_count }} + {{ ''|placeholder }} + {% endif %} + + + + + @@ -69,6 +79,13 @@ {% include 'inc/paginator.html' with paginator=sites_table.paginator page=sites_table.page %} +
+
Providers
+
+ {% render_table providers_table 'inc/table.html' %} + {% include 'inc/paginator.html' with paginator=providers_table.paginator page=providers_table.page %} +
+
{% plugin_full_width_page object %} From 7a546587107a828778ce172da9c6d5983e75efa0 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 31 Mar 2022 09:03:01 -0400 Subject: [PATCH 24/94] Fixes #8978: Fix instantiation of front ports when provisioning a module --- docs/release-notes/version-3.2.md | 1 + netbox/dcim/models/device_component_templates.py | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index d420b8108..072506a45 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -155,6 +155,7 @@ Where it is desired to limit the range of available VLANs within a group, users * [#8872](https://github.com/netbox-community/netbox/issues/8872) - Enable filtering by custom object fields * [#8970](https://github.com/netbox-community/netbox/issues/8970) - Permit nested inventory item templates on device types * [#8976](https://github.com/netbox-community/netbox/issues/8976) - Add missing `object_type` field on CustomField REST API serializer +* [#8978](https://github.com/netbox-community/netbox/issues/8978) - Fix instantiation of front ports when provisioning a module ### Other Changes diff --git a/netbox/dcim/models/device_component_templates.py b/netbox/dcim/models/device_component_templates.py index 0538704d2..01f1cd1be 100644 --- a/netbox/dcim/models/device_component_templates.py +++ b/netbox/dcim/models/device_component_templates.py @@ -280,7 +280,8 @@ class PowerOutletTemplate(ModularComponentTemplateModel): def instantiate(self, **kwargs): if self.power_port: - power_port = PowerPort.objects.get(name=self.power_port.name, **kwargs) + power_port_name = self.power_port.resolve_name(kwargs.get('module')) + power_port = PowerPort.objects.get(name=power_port_name, **kwargs) else: power_port = None return self.component_model( @@ -390,7 +391,8 @@ class FrontPortTemplate(ModularComponentTemplateModel): def instantiate(self, **kwargs): if self.rear_port: - rear_port = RearPort.objects.get(name=self.rear_port.name, **kwargs) + rear_port_name = self.rear_port.resolve_name(kwargs.get('module')) + rear_port = RearPort.objects.get(name=rear_port_name, **kwargs) else: rear_port = None return self.component_model( From 1d55c04c21d3d2c80f0c1f586ae93983db676703 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 31 Mar 2022 11:40:02 -0400 Subject: [PATCH 25/94] Closes #9006: Enable custom fields, custom links, and tags for journal entries --- docs/release-notes/version-3.2.md | 5 +++- netbox/extras/api/serializers.py | 6 ++-- netbox/extras/filtersets.py | 8 ++---- netbox/extras/forms/filtersets.py | 11 +++++--- netbox/extras/forms/models.py | 8 +++--- netbox/extras/graphql/types.py | 3 +- .../0073_journalentry_tags_custom_fields.py | 23 +++++++++++++++ netbox/extras/models/models.py | 6 ++-- netbox/extras/tables/tables.py | 28 ++++++++----------- netbox/netbox/views/generic/feature_views.py | 4 ++- netbox/templates/extras/journalentry.html | 6 ++-- netbox/templates/extras/object_journal.html | 6 +--- 12 files changed, 68 insertions(+), 46 deletions(-) create mode 100644 netbox/extras/migrations/0073_journalentry_tags_custom_fields.py diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index 072506a45..c6f5ecc31 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -146,6 +146,7 @@ Where it is desired to limit the range of available VLANs within a group, users * [#8572](https://github.com/netbox-community/netbox/issues/8572) - Add a `pre_run()` method for reports * [#8593](https://github.com/netbox-community/netbox/issues/8593) - Add a `link` field for contacts * [#8649](https://github.com/netbox-community/netbox/issues/8649) - Enable customization of configuration module using `NETBOX_CONFIGURATION` environment variable +* [#9006](https://github.com/netbox-community/netbox/issues/9006) - Enable custom fields, custom links, and tags for journal entries ### Bug Fixes (From Beta2) @@ -207,11 +208,13 @@ Where it is desired to limit the range of available VLANs within a group, users * Added `data_type` and `object_type` fields * extras.CustomLink * Added `enabled` field +* extras.JournalEntry + * Added `custom_fields` and `tags` fields * ipam.ASN * Added `provider_count` field * ipam.VLANGroup * Added the `/availables-vlans/` endpoint - * Added the `min_vid` and `max_vid` fields + * Added `min_vid` and `max_vid` fields * tenancy.Contact * Added `link` field * virtualization.VMInterface diff --git a/netbox/extras/api/serializers.py b/netbox/extras/api/serializers.py index 5ab8beb13..e05d4083c 100644 --- a/netbox/extras/api/serializers.py +++ b/netbox/extras/api/serializers.py @@ -14,7 +14,7 @@ from extras.models import * from extras.utils import FeatureQuery from netbox.api import ChoiceField, ContentTypeField, SerializedPKRelatedField from netbox.api.exceptions import SerializerNotFound -from netbox.api.serializers import BaseModelSerializer, ValidatedModelSerializer +from netbox.api.serializers import BaseModelSerializer, NetBoxModelSerializer, ValidatedModelSerializer from tenancy.api.nested_serializers import NestedTenantSerializer, NestedTenantGroupSerializer from tenancy.models import Tenant, TenantGroup from users.api.nested_serializers import NestedUserSerializer @@ -200,7 +200,7 @@ class ImageAttachmentSerializer(ValidatedModelSerializer): # Journal entries # -class JournalEntrySerializer(ValidatedModelSerializer): +class JournalEntrySerializer(NetBoxModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='extras-api:journalentry-detail') assigned_object_type = ContentTypeField( queryset=ContentType.objects.all() @@ -221,7 +221,7 @@ class JournalEntrySerializer(ValidatedModelSerializer): model = JournalEntry fields = [ 'id', 'url', 'display', 'assigned_object_type', 'assigned_object_id', 'assigned_object', 'created', - 'created_by', 'kind', 'comments', + 'created_by', 'kind', 'comments', 'tags', 'custom_fields', ] def validate(self, data): diff --git a/netbox/extras/filtersets.py b/netbox/extras/filtersets.py index 8f231ffb7..25477fbda 100644 --- a/netbox/extras/filtersets.py +++ b/netbox/extras/filtersets.py @@ -4,7 +4,7 @@ from django.contrib.contenttypes.models import ContentType from django.db.models import Q from dcim.models import DeviceRole, DeviceType, Platform, Region, Site, SiteGroup -from netbox.filtersets import BaseFilterSet, ChangeLoggedModelFilterSet +from netbox.filtersets import BaseFilterSet, ChangeLoggedModelFilterSet, NetBoxModelFilterSet from tenancy.models import Tenant, TenantGroup from utilities.filters import ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter from virtualization.models import Cluster, ClusterGroup, ClusterType @@ -134,11 +134,7 @@ class ImageAttachmentFilterSet(BaseFilterSet): return queryset.filter(name__icontains=value) -class JournalEntryFilterSet(ChangeLoggedModelFilterSet): - q = django_filters.CharFilter( - method='search', - label='Search', - ) +class JournalEntryFilterSet(NetBoxModelFilterSet): created = django_filters.DateTimeFromToRangeFilter() assigned_object_type = ContentTypeFilter() created_by_id = django_filters.ModelMultipleChoiceFilter( diff --git a/netbox/extras/forms/filtersets.py b/netbox/extras/forms/filtersets.py index e3ae9b1f3..5d66c8be8 100644 --- a/netbox/extras/forms/filtersets.py +++ b/netbox/extras/forms/filtersets.py @@ -7,10 +7,12 @@ from dcim.models import DeviceRole, DeviceType, Platform, Region, Site, SiteGrou from extras.choices import * from extras.models import * from extras.utils import FeatureQuery +from netbox.forms.base import NetBoxModelFilterSetForm from tenancy.models import Tenant, TenantGroup from utilities.forms import ( - add_blank_choice, APISelectMultiple, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker, - DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, BOOLEAN_WITH_BLANK_CHOICES, + add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField, + ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, + StaticSelect, TagFilterField, ) from virtualization.models import Cluster, ClusterGroup, ClusterType @@ -237,10 +239,10 @@ class LocalConfigContextFilterForm(forms.Form): ) -class JournalEntryFilterForm(FilterForm): +class JournalEntryFilterForm(NetBoxModelFilterSetForm): model = JournalEntry fieldsets = ( - (None, ('q',)), + (None, ('q', 'tag')), ('Creation', ('created_before', 'created_after', 'created_by_id')), ('Attributes', ('assigned_object_type_id', 'kind')) ) @@ -275,6 +277,7 @@ class JournalEntryFilterForm(FilterForm): required=False, widget=StaticSelect() ) + tag = TagFilterField(model) class ObjectChangeFilterForm(FilterForm): diff --git a/netbox/extras/forms/models.py b/netbox/extras/forms/models.py index 78b627662..112911f42 100644 --- a/netbox/extras/forms/models.py +++ b/netbox/extras/forms/models.py @@ -5,6 +5,7 @@ from dcim.models import DeviceRole, DeviceType, Platform, Region, Site, SiteGrou from extras.choices import * from extras.models import * from extras.utils import FeatureQuery +from netbox.forms import NetBoxModelForm from tenancy.models import Tenant, TenantGroup from utilities.forms import ( add_blank_choice, BootstrapMixin, CommentField, ContentTypeChoiceField, ContentTypeMultipleChoiceField, @@ -219,18 +220,17 @@ class ImageAttachmentForm(BootstrapMixin, forms.ModelForm): ] -class JournalEntryForm(BootstrapMixin, forms.ModelForm): - comments = CommentField() - +class JournalEntryForm(NetBoxModelForm): kind = forms.ChoiceField( choices=add_blank_choice(JournalEntryKindChoices), required=False, widget=StaticSelect() ) + comments = CommentField() class Meta: model = JournalEntry - fields = ['assigned_object_type', 'assigned_object_id', 'kind', 'comments'] + fields = ['assigned_object_type', 'assigned_object_id', 'kind', 'tags', 'comments'] widgets = { 'assigned_object_type': forms.HiddenInput, 'assigned_object_id': forms.HiddenInput, diff --git a/netbox/extras/graphql/types.py b/netbox/extras/graphql/types.py index c5f34a11e..dbaa0bee2 100644 --- a/netbox/extras/graphql/types.py +++ b/netbox/extras/graphql/types.py @@ -1,4 +1,5 @@ from extras import filtersets, models +from extras.graphql.mixins import CustomFieldsMixin, TagsMixin from netbox.graphql.types import BaseObjectType, ObjectType __all__ = ( @@ -54,7 +55,7 @@ class ImageAttachmentType(BaseObjectType): filterset_class = filtersets.ImageAttachmentFilterSet -class JournalEntryType(ObjectType): +class JournalEntryType(CustomFieldsMixin, TagsMixin, ObjectType): class Meta: model = models.JournalEntry diff --git a/netbox/extras/migrations/0073_journalentry_tags_custom_fields.py b/netbox/extras/migrations/0073_journalentry_tags_custom_fields.py new file mode 100644 index 000000000..73a3e466c --- /dev/null +++ b/netbox/extras/migrations/0073_journalentry_tags_custom_fields.py @@ -0,0 +1,23 @@ +import django.core.serializers.json +from django.db import migrations, models +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0072_created_datetimefield'), + ] + + operations = [ + migrations.AddField( + model_name='journalentry', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder), + ), + migrations.AddField( + model_name='journalentry', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + ] diff --git a/netbox/extras/models/models.py b/netbox/extras/models/models.py index 5eb5a4a02..ef0ab8b1f 100644 --- a/netbox/extras/models/models.py +++ b/netbox/extras/models/models.py @@ -19,7 +19,9 @@ from extras.constants import * from extras.conditions import ConditionSet from extras.utils import FeatureQuery, image_upload from netbox.models import ChangeLoggedModel -from netbox.models.features import ExportTemplatesMixin, JobResultsMixin, WebhooksMixin +from netbox.models.features import ( + CustomFieldsMixin, CustomLinksMixin, ExportTemplatesMixin, JobResultsMixin, TagsMixin, WebhooksMixin, +) from utilities.querysets import RestrictedQuerySet from utilities.utils import render_jinja2 @@ -419,7 +421,7 @@ class ImageAttachment(WebhooksMixin, ChangeLoggedModel): return objectchange -class JournalEntry(WebhooksMixin, ChangeLoggedModel): +class JournalEntry(CustomFieldsMixin, CustomLinksMixin, TagsMixin, WebhooksMixin, ChangeLoggedModel): """ A historical remark concerning an object; collectively, these form an object's journal. The journal is used to preserve historical context around an object, and complements NetBox's built-in change logging. For example, you diff --git a/netbox/extras/tables/tables.py b/netbox/extras/tables/tables.py index 964327558..a13054d56 100644 --- a/netbox/extras/tables/tables.py +++ b/netbox/extras/tables/tables.py @@ -12,7 +12,6 @@ __all__ = ( 'ExportTemplateTable', 'JournalEntryTable', 'ObjectChangeTable', - 'ObjectJournalTable', 'TaggedItemTable', 'TagTable', 'WebhookTable', @@ -210,25 +209,11 @@ class ObjectChangeTable(NetBoxTable): ) -class ObjectJournalTable(NetBoxTable): - """ - Used for displaying a set of JournalEntries within the context of a single object. - """ +class JournalEntryTable(NetBoxTable): created = tables.DateTimeColumn( linkify=True, format=settings.SHORT_DATETIME_FORMAT ) - kind = columns.ChoiceFieldColumn() - comments = tables.TemplateColumn( - template_code='{{ value|markdown|truncatewords_html:50 }}' - ) - - class Meta(NetBoxTable.Meta): - model = JournalEntry - fields = ('id', 'created', 'created_by', 'kind', 'comments', 'actions') - - -class JournalEntryTable(ObjectJournalTable): assigned_object_type = columns.ContentTypeColumn( verbose_name='Object type' ) @@ -237,13 +222,22 @@ class JournalEntryTable(ObjectJournalTable): orderable=False, verbose_name='Object' ) + kind = columns.ChoiceFieldColumn() comments = columns.MarkdownColumn() + comments_short = tables.TemplateColumn( + accessor=tables.A('comments'), + template_code='{{ value|markdown|truncatewords_html:50 }}', + verbose_name='Comments (Short)' + ) + tags = columns.TagColumn( + url_name='extras:journalentry_list' + ) class Meta(NetBoxTable.Meta): model = JournalEntry fields = ( 'pk', 'id', 'created', 'created_by', 'assigned_object_type', 'assigned_object', 'kind', 'comments', - 'actions', + 'comments_short', 'tags', 'actions', ) default_columns = ( 'pk', 'created', 'created_by', 'assigned_object_type', 'assigned_object', 'kind', 'comments' diff --git a/netbox/netbox/views/generic/feature_views.py b/netbox/netbox/views/generic/feature_views.py index 73ced0d65..85e675a69 100644 --- a/netbox/netbox/views/generic/feature_views.py +++ b/netbox/netbox/views/generic/feature_views.py @@ -86,8 +86,10 @@ class ObjectJournalView(View): assigned_object_type=content_type, assigned_object_id=obj.pk ) - journalentry_table = tables.ObjectJournalTable(journalentries) + journalentry_table = tables.JournalEntryTable(journalentries, user=request.user) journalentry_table.configure(request) + journalentry_table.columns.hide('assigned_object_type') + journalentry_table.columns.hide('assigned_object') if request.user.has_perm('extras.add_journalentry'): form = forms.JournalEntryForm( diff --git a/netbox/templates/extras/journalentry.html b/netbox/templates/extras/journalentry.html index 6d1d9599c..d8f8114b5 100644 --- a/netbox/templates/extras/journalentry.html +++ b/netbox/templates/extras/journalentry.html @@ -9,7 +9,7 @@ {% block content %}
-
+
Journal Entry @@ -35,8 +35,10 @@
ASN{{ object.asn|placeholder }}ASN + {% if object.asn %} +
+ +
+ {% endif %} + {{ object.asn|placeholder }} +
ASNs + {% for asn in object.asns.all %} + {{ asn|linkify }}{% if not forloop.last %}, {% endif %} + {% empty %} + {{ ''|placeholder }} + {% endfor %} +
Account
Providers + {% if providers_count %} + {{ providers_count }} + {% else %} + {{ ''|placeholder }} {% endif %}
+ {% include 'inc/panels/custom_fields.html' %} + {% include 'inc/panels/tags.html' %}
-
+
{% include 'inc/panels/comments.html' %}
diff --git a/netbox/templates/extras/object_journal.html b/netbox/templates/extras/object_journal.html index 5f3b991fa..363b067a8 100644 --- a/netbox/templates/extras/object_journal.html +++ b/netbox/templates/extras/object_journal.html @@ -11,11 +11,7 @@

New Journal Entry

{% csrf_token %} - {% for field in form.hidden_fields %} - {{ field }} - {% endfor %} - {% render_field form.kind %} - {% render_field form.comments %} + {% render_form form %}
Cancel From 4fae42de510846f83ab5f7ab91b3049d6ed046b4 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 31 Mar 2022 12:07:02 -0400 Subject: [PATCH 26/94] Fixes #9007: Fix FieldError exception when instantiating a device type with nested inventory items --- docs/release-notes/version-3.2.md | 1 + netbox/dcim/models/device_component_templates.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index c6f5ecc31..5ba8a4371 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -157,6 +157,7 @@ Where it is desired to limit the range of available VLANs within a group, users * [#8970](https://github.com/netbox-community/netbox/issues/8970) - Permit nested inventory item templates on device types * [#8976](https://github.com/netbox-community/netbox/issues/8976) - Add missing `object_type` field on CustomField REST API serializer * [#8978](https://github.com/netbox-community/netbox/issues/8978) - Fix instantiation of front ports when provisioning a module +* [#9007](https://github.com/netbox-community/netbox/issues/9007) - Fix FieldError exception when instantiating a device type with nested inventory items ### Other Changes diff --git a/netbox/dcim/models/device_component_templates.py b/netbox/dcim/models/device_component_templates.py index 01f1cd1be..b363d6ea4 100644 --- a/netbox/dcim/models/device_component_templates.py +++ b/netbox/dcim/models/device_component_templates.py @@ -551,7 +551,7 @@ class InventoryItemTemplate(MPTTModel, ComponentTemplateModel): unique_together = ('device_type', 'parent', 'name') def instantiate(self, **kwargs): - parent = InventoryItemTemplate.objects.get(name=self.parent.name, **kwargs) if self.parent else None + parent = InventoryItem.objects.get(name=self.parent.name, **kwargs) if self.parent else None if self.component: model = self.component.component_model component = model.objects.get(name=self.component.name, **kwargs) From a84ae88214b88a81af9ed96e9022d6e5a837f969 Mon Sep 17 00:00:00 2001 From: kkthxbye <> Date: Fri, 1 Apr 2022 09:34:16 +0200 Subject: [PATCH 27/94] Annotate rack search queryset with device count --- netbox/netbox/constants.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/netbox/netbox/constants.py b/netbox/netbox/constants.py index 45de4d5b2..bc58ee5e4 100644 --- a/netbox/netbox/constants.py +++ b/netbox/netbox/constants.py @@ -65,7 +65,9 @@ DCIM_TYPES = OrderedDict( 'url': 'dcim:site_list', }), ('rack', { - 'queryset': Rack.objects.prefetch_related('site', 'location', 'tenant', 'role'), + 'queryset': Rack.objects.prefetch_related('site', 'location', 'tenant', 'role').annotate( + device_count=count_related(Device, 'rack') + ), 'filterset': RackFilterSet, 'table': RackTable, 'url': 'dcim:rack_list', From 35f3a42e7f8d6eb82448d73f25145a7a7f335de2 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Fri, 1 Apr 2022 08:31:53 -0400 Subject: [PATCH 28/94] Remove 2022 survey announcement --- README.md | 2 -- docs/index.md | 2 -- 2 files changed, 4 deletions(-) diff --git a/README.md b/README.md index 42bf8b619..8429cd4b3 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,6 @@ NetBox logo
-:loudspeaker: The **[2022 NetBox community survey](https://forms.gle/KR8YbR8GiJ9EYXM28)** is now open! We collect this feedback and demographic data from NetBox users around the world to help shape the project's long-term development goals. Please take a few minutes to share your responses! - ![Master branch build status](https://github.com/netbox-community/netbox/workflows/CI/badge.svg?branch=master) NetBox is an infrastructure resource modeling (IRM) tool designed to empower diff --git a/docs/index.md b/docs/index.md index 5742c0ab6..943f1d7ab 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,7 +1,5 @@ ![NetBox](netbox_logo.svg "NetBox logo"){style="height: 100px; margin-bottom: 3em"} -:loudspeaker: The **[2022 NetBox community survey](https://forms.gle/KR8YbR8GiJ9EYXM28)** is now open! We collect this feedback and demographic data from NetBox users around the world to help shape the project's long-term development goals. Please take a few minutes to share your responses! - # What is NetBox? NetBox is an infrastructure resource modeling (IRM) application designed to empower network automation. Initially conceived by the network engineering team at [DigitalOcean](https://www.digitalocean.com/), NetBox was developed specifically to address the needs of network and infrastructure engineers. NetBox is made available as open source under the Apache 2 license. It encompasses the following aspects of network management: From 99a01207bcf3202d04986862398d3934bb5e912a Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Fri, 1 Apr 2022 09:06:44 -0400 Subject: [PATCH 29/94] Closes #9012: Linkify circuits count in providers list --- docs/release-notes/version-3.1.md | 2 ++ netbox/circuits/tables.py | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/release-notes/version-3.1.md b/docs/release-notes/version-3.1.md index 7e8e93632..bab66f2ad 100644 --- a/docs/release-notes/version-3.1.md +++ b/docs/release-notes/version-3.1.md @@ -9,10 +9,12 @@ * [#8790](https://github.com/netbox-community/netbox/issues/8790) - Include site and prefixes columns in VLAN group VLANs table * [#8830](https://github.com/netbox-community/netbox/issues/8830) - Add Checkpoint ClusterXL protocol for FHRP groups * [#8974](https://github.com/netbox-community/netbox/issues/8974) - Use monospace font for text areas in config revision form +* [#9012](https://github.com/netbox-community/netbox/issues/9012) - Linkify circuits count in providers list ### Bug Fixes * [#8866](https://github.com/netbox-community/netbox/issues/8866) - Prevent exception when searching for a rack position with no rack specified under device edit view +* [#9009](https://github.com/netbox-community/netbox/issues/9009) - Fix device count for racks in global search results --- diff --git a/netbox/circuits/tables.py b/netbox/circuits/tables.py index b4e0c7d2d..76fb96aaf 100644 --- a/netbox/circuits/tables.py +++ b/netbox/circuits/tables.py @@ -2,7 +2,9 @@ import django_tables2 as tables from django_tables2.utils import Accessor from tenancy.tables import TenantColumn -from utilities.tables import BaseTable, ButtonsColumn, ChoiceFieldColumn, MarkdownColumn, TagColumn, ToggleColumn +from utilities.tables import ( + BaseTable, ButtonsColumn, ChoiceFieldColumn, LinkedCountColumn, MarkdownColumn, TagColumn, ToggleColumn, +) from .models import * @@ -53,8 +55,10 @@ class ProviderTable(BaseTable): name = tables.Column( linkify=True ) - circuit_count = tables.Column( + circuit_count = LinkedCountColumn( accessor=Accessor('count_circuits'), + viewname='circuits:circuit_list', + url_params={'provider_id': 'pk'}, verbose_name='Circuits' ) comments = MarkdownColumn() From 7fff1e6fe5d42c3ba0ec7164da56e14b055d673a Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Fri, 1 Apr 2022 09:42:30 -0400 Subject: [PATCH 30/94] Closes #9003: Enable bulk module assignment/removal for device components --- netbox/dcim/forms/bulk_edit.py | 81 ++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/netbox/dcim/forms/bulk_edit.py b/netbox/dcim/forms/bulk_edit.py index 92496e6b0..03ac062a3 100644 --- a/netbox/dcim/forms/bulk_edit.py +++ b/netbox/dcim/forms/bulk_edit.py @@ -912,9 +912,33 @@ class InventoryItemTemplateBulkEditForm(BulkEditForm): # Device components # +class ComponentBulkEditForm(NetBoxModelBulkEditForm): + device = forms.ModelChoiceField( + queryset=Device.objects.all(), + required=False, + disabled=True, + widget=forms.HiddenInput() + ) + module = forms.ModelChoiceField( + queryset=Module.objects.all(), + required=False + ) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Limit module queryset to Modules which belong to the parent Device + if 'device' in self.initial: + device = Device.objects.filter(pk=self.initial['device']).first() + self.fields['module'].queryset = Module.objects.filter(device=device) + else: + self.fields['module'].choices = () + self.fields['module'].widget.attrs['disabled'] = True + + class ConsolePortBulkEditForm( form_from_model(ConsolePort, ['label', 'type', 'speed', 'mark_connected', 'description']), - NetBoxModelBulkEditForm + ComponentBulkEditForm ): mark_connected = forms.NullBooleanField( required=False, @@ -923,14 +947,14 @@ class ConsolePortBulkEditForm( model = ConsolePort fieldsets = ( - (None, ('type', 'label', 'speed', 'description', 'mark_connected')), + (None, ('module', 'type', 'label', 'speed', 'description', 'mark_connected')), ) - nullable_fields = ('label', 'description') + nullable_fields = ('module', 'label', 'description') class ConsoleServerPortBulkEditForm( form_from_model(ConsoleServerPort, ['label', 'type', 'speed', 'mark_connected', 'description']), - NetBoxModelBulkEditForm + ComponentBulkEditForm ): mark_connected = forms.NullBooleanField( required=False, @@ -939,14 +963,14 @@ class ConsoleServerPortBulkEditForm( model = ConsoleServerPort fieldsets = ( - (None, ('type', 'label', 'speed', 'description', 'mark_connected')), + (None, ('module', 'type', 'label', 'speed', 'description', 'mark_connected')), ) - nullable_fields = ('label', 'description') + nullable_fields = ('module', 'label', 'description') class PowerPortBulkEditForm( form_from_model(PowerPort, ['label', 'type', 'maximum_draw', 'allocated_draw', 'mark_connected', 'description']), - NetBoxModelBulkEditForm + ComponentBulkEditForm ): mark_connected = forms.NullBooleanField( required=False, @@ -955,22 +979,16 @@ class PowerPortBulkEditForm( model = PowerPort fieldsets = ( - (None, ('type', 'label', 'description', 'mark_connected')), + (None, ('module', 'type', 'label', 'description', 'mark_connected')), ('Power', ('maximum_draw', 'allocated_draw')), ) - nullable_fields = ('label', 'description') + nullable_fields = ('module', 'label', 'description') class PowerOutletBulkEditForm( form_from_model(PowerOutlet, ['label', 'type', 'feed_leg', 'power_port', 'mark_connected', 'description']), - NetBoxModelBulkEditForm + ComponentBulkEditForm ): - device = forms.ModelChoiceField( - queryset=Device.objects.all(), - required=False, - disabled=True, - widget=forms.HiddenInput() - ) mark_connected = forms.NullBooleanField( required=False, widget=BulkEditNullBooleanSelect @@ -978,10 +996,10 @@ class PowerOutletBulkEditForm( model = PowerOutlet fieldsets = ( - (None, ('type', 'label', 'description', 'mark_connected')), + (None, ('module', 'type', 'label', 'description', 'mark_connected')), ('Power', ('feed_leg', 'power_port')), ) - nullable_fields = ('label', 'type', 'feed_leg', 'power_port', 'description') + nullable_fields = ('module', 'label', 'type', 'feed_leg', 'power_port', 'description') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -1001,14 +1019,8 @@ class InterfaceBulkEditForm( 'mark_connected', 'description', 'mode', 'rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', ]), - NetBoxModelBulkEditForm + ComponentBulkEditForm ): - device = forms.ModelChoiceField( - queryset=Device.objects.all(), - required=False, - disabled=True, - widget=forms.HiddenInput() - ) enabled = forms.NullBooleanField( required=False, widget=BulkEditNullBooleanSelect @@ -1059,7 +1071,7 @@ class InterfaceBulkEditForm( model = Interface fieldsets = ( - (None, ('type', 'label', 'speed', 'duplex', 'description')), + (None, ('module', 'type', 'label', 'speed', 'duplex', 'description')), ('Addressing', ('vrf', 'mac_address', 'wwn')), ('Operation', ('mtu', 'tx_power', 'enabled', 'mgmt_only', 'mark_connected')), ('Related Interfaces', ('parent', 'bridge', 'lag')), @@ -1067,8 +1079,9 @@ class InterfaceBulkEditForm( ('Wireless', ('rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width')), ) nullable_fields = ( - 'label', 'parent', 'bridge', 'lag', 'speed', 'duplex', 'mac_address', 'wwn', 'mtu', 'description', 'mode', - 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'untagged_vlan', 'tagged_vlans', 'vrf', + 'module', 'label', 'parent', 'bridge', 'lag', 'speed', 'duplex', 'mac_address', 'wwn', 'mtu', 'description', + 'mode', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'untagged_vlan', 'tagged_vlans', + 'vrf', ) def __init__(self, *args, **kwargs): @@ -1133,24 +1146,24 @@ class InterfaceBulkEditForm( class FrontPortBulkEditForm( form_from_model(FrontPort, ['label', 'type', 'color', 'mark_connected', 'description']), - NetBoxModelBulkEditForm + ComponentBulkEditForm ): model = FrontPort fieldsets = ( - (None, ('type', 'label', 'color', 'description', 'mark_connected')), + (None, ('module', 'type', 'label', 'color', 'description', 'mark_connected')), ) - nullable_fields = ('label', 'description') + nullable_fields = ('module', 'label', 'description') class RearPortBulkEditForm( form_from_model(RearPort, ['label', 'type', 'color', 'mark_connected', 'description']), - NetBoxModelBulkEditForm + ComponentBulkEditForm ): model = RearPort fieldsets = ( - (None, ('type', 'label', 'color', 'description', 'mark_connected')), + (None, ('module', 'type', 'label', 'color', 'description', 'mark_connected')), ) - nullable_fields = ('label', 'description') + nullable_fields = ('module', 'label', 'description') class ModuleBayBulkEditForm( From e2b6d69596f76d9f4cbaa2b479bda297febfef62 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Fri, 1 Apr 2022 10:15:45 -0400 Subject: [PATCH 31/94] Monkey-patch Django's force_text in lieu of graphene-django 2.16 release --- netbox/netbox/settings.py | 7 +++++++ requirements.txt | 3 +-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index e78135aa3..615ee8bed 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -14,6 +14,13 @@ from django.core.validators import URLValidator from netbox.config import PARAMS +# Monkey patch to fix Django 4.0 support for graphene-django (see +# https://github.com/graphql-python/graphene-django/issues/1284) +# TODO: Remove this when graphene-django 2.16 becomes available +import django +from django.utils.encoding import force_str +django.utils.encoding.force_text = force_str + # # Environment setup diff --git a/requirements.txt b/requirements.txt index ee24e0a6c..39e3630ca 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,8 +13,7 @@ django-taggit==2.1.0 django-timezone-field==5.0 djangorestframework==3.13.1 drf-yasg[validation]==1.20.0 -# Installing from branch pending v2.16 release -git+https://github.com/graphql-python/graphene-django.git@v2 +graphene-django==2.15.0 gunicorn==20.1.0 Jinja2==3.0.3 Markdown==3.3.6 From 780459d2bfd76d12c4125a31a20c6c0cee26ee09 Mon Sep 17 00:00:00 2001 From: Stephan Blanke Date: Sat, 2 Apr 2022 18:08:48 +0200 Subject: [PATCH 32/94] Closes #8365: Filtering for child devices by parent device --- netbox/dcim/filtersets.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py index 504ad69ca..534a71762 100644 --- a/netbox/dcim/filtersets.py +++ b/netbox/dcim/filtersets.py @@ -639,6 +639,11 @@ class DeviceFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilte to_field_name='slug', label='Role (slug)', ) + parent_device_id = django_filters.ModelMultipleChoiceFilter( + field_name='parent_bay__device', + queryset=Device.objects.all(), + label='Parent Device (ID)', + ) platform_id = django_filters.ModelMultipleChoiceFilter( queryset=Platform.objects.all(), label='Platform (ID)', From 36d6ae33d15e93cc552827cdea363a9c00c7f823 Mon Sep 17 00:00:00 2001 From: kkthxbye-code Date: Mon, 4 Apr 2022 18:00:38 +0200 Subject: [PATCH 33/94] Allow setting individual timeouts on scripts and reports --- docs/customization/custom-scripts.md | 4 ++++ netbox/extras/api/views.py | 6 ++++-- netbox/extras/management/commands/runreport.py | 3 ++- netbox/extras/models/models.py | 6 ++++-- netbox/extras/reports.py | 1 + netbox/extras/scripts.py | 6 +++++- netbox/extras/views.py | 7 +++++-- 7 files changed, 25 insertions(+), 8 deletions(-) diff --git a/docs/customization/custom-scripts.md b/docs/customization/custom-scripts.md index 02af19726..982a4f8e3 100644 --- a/docs/customization/custom-scripts.md +++ b/docs/customization/custom-scripts.md @@ -89,6 +89,10 @@ The checkbox to commit database changes when executing a script is checked by de commit_default = False ``` +### `job_timeout` + +Set the allowed runtime of a script. If not set the `RQ_DEFAULT_TIMEOUT` will be used. + ## Accessing Request Data Details of the current HTTP request (the one being made to execute the script) are available as the instance attribute `self.request`. This can be used to infer, for example, the user executing the script and the client IP address: diff --git a/netbox/extras/api/views.py b/netbox/extras/api/views.py index 4f42b4c93..579e39d86 100644 --- a/netbox/extras/api/views.py +++ b/netbox/extras/api/views.py @@ -236,7 +236,8 @@ class ReportViewSet(ViewSet): run_report, report.full_name, report_content_type, - request.user + request.user, + job_timeout=report.job_timeout ) report.result = job_result @@ -320,7 +321,8 @@ class ScriptViewSet(ViewSet): request.user, data=data, request=copy_safe_request(request), - commit=commit + commit=commit, + job_timeout=script.job_timeout, ) script.result = job_result serializer = serializers.ScriptDetailSerializer(script, context={'request': request}) diff --git a/netbox/extras/management/commands/runreport.py b/netbox/extras/management/commands/runreport.py index de7c5c91b..ee166ae6a 100644 --- a/netbox/extras/management/commands/runreport.py +++ b/netbox/extras/management/commands/runreport.py @@ -35,7 +35,8 @@ class Command(BaseCommand): run_report, report.full_name, report_content_type, - None + None, + job_timeout=report.job_timeout ) # Wait on the job to finish diff --git a/netbox/extras/models/models.py b/netbox/extras/models/models.py index ef0ab8b1f..48a076f75 100644 --- a/netbox/extras/models/models.py +++ b/netbox/extras/models/models.py @@ -13,6 +13,7 @@ from django.urls import reverse from django.utils import timezone from django.utils.formats import date_format from rest_framework.utils.encoders import JSONEncoder +import django_rq from extras.choices import * from extras.constants import * @@ -549,8 +550,9 @@ class JobResult(models.Model): user=user, job_id=uuid.uuid4() ) - - func.delay(*args, job_id=str(job_result.job_id), job_result=job_result, **kwargs) + + queue = django_rq.get_queue("default") + queue.enqueue(func, job_id=str(job_result.job_id), job_result=job_result, **kwargs) return job_result diff --git a/netbox/extras/reports.py b/netbox/extras/reports.py index 2eb6584c9..0bdc4847e 100644 --- a/netbox/extras/reports.py +++ b/netbox/extras/reports.py @@ -119,6 +119,7 @@ class Report(object): } """ description = None + job_timeout = None def __init__(self): diff --git a/netbox/extras/scripts.py b/netbox/extras/scripts.py index f80dfaefa..4b9d17d67 100644 --- a/netbox/extras/scripts.py +++ b/netbox/extras/scripts.py @@ -298,6 +298,10 @@ class BaseScript: def module(cls): return cls.__module__ + @classproperty + def job_timeout(self): + return getattr(self.Meta, 'job_timeout', None) + @classmethod def _get_vars(cls): vars = {} @@ -414,7 +418,7 @@ def is_variable(obj): return isinstance(obj, ScriptVariable) -@job('default') +#@job('default') def run_script(data, request, commit=True, *args, **kwargs): """ A wrapper for calling Script.run(). This performs error handling and provides a hook for committing changes. It diff --git a/netbox/extras/views.py b/netbox/extras/views.py index 0a190dd49..785c5eb5a 100644 --- a/netbox/extras/views.py +++ b/netbox/extras/views.py @@ -588,7 +588,8 @@ class ReportView(ContentTypePermissionRequiredMixin, View): run_report, report.full_name, report_content_type, - request.user + request.user, + job_timeout=report.job_timeout ) return redirect('extras:report_result', job_result_pk=job_result.pk) @@ -708,6 +709,7 @@ class ScriptView(ContentTypePermissionRequiredMixin, GetScriptMixin, View): commit = form.cleaned_data.pop('_commit') script_content_type = ContentType.objects.get(app_label='extras', model='script') + job_result = JobResult.enqueue_job( run_script, script.full_name, @@ -715,7 +717,8 @@ class ScriptView(ContentTypePermissionRequiredMixin, GetScriptMixin, View): request.user, data=form.cleaned_data, request=copy_safe_request(request), - commit=commit + commit=commit, + job_timeout=script.job_timeout, ) return redirect('extras:script_result', job_result_pk=job_result.pk) From 69b4d0d44b5f119dad14003e00dc78872cd836cb Mon Sep 17 00:00:00 2001 From: kkthxbye-code Date: Mon, 4 Apr 2022 18:13:13 +0200 Subject: [PATCH 34/94] #9028 - Fix pep8 syntax --- netbox/extras/models/models.py | 2 +- netbox/extras/scripts.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/netbox/extras/models/models.py b/netbox/extras/models/models.py index 48a076f75..e614a1258 100644 --- a/netbox/extras/models/models.py +++ b/netbox/extras/models/models.py @@ -550,7 +550,7 @@ class JobResult(models.Model): user=user, job_id=uuid.uuid4() ) - + queue = django_rq.get_queue("default") queue.enqueue(func, job_id=str(job_result.job_id), job_result=job_result, **kwargs) diff --git a/netbox/extras/scripts.py b/netbox/extras/scripts.py index 4b9d17d67..5351bca8a 100644 --- a/netbox/extras/scripts.py +++ b/netbox/extras/scripts.py @@ -418,7 +418,6 @@ def is_variable(obj): return isinstance(obj, ScriptVariable) -#@job('default') def run_script(data, request, commit=True, *args, **kwargs): """ A wrapper for calling Script.run(). This performs error handling and provides a hook for committing changes. It From ea88b040ec4b96c09bb0fde15402765ac904a7a5 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 4 Apr 2022 14:40:22 -0400 Subject: [PATCH 35/94] Fixes #8658: Fix display of assigned components under inventory item lists --- docs/release-notes/version-3.2.md | 1 + netbox/dcim/tables/devices.py | 1 - netbox/netbox/views/generic/object_views.py | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index 5ba8a4371..a0ba35953 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -150,6 +150,7 @@ Where it is desired to limit the range of available VLANs within a group, users ### Bug Fixes (From Beta2) +* [#8658](https://github.com/netbox-community/netbox/issues/8658) - Fix display of assigned components under inventory item lists * [#8838](https://github.com/netbox-community/netbox/issues/8838) - Fix FieldError exception during global search * [#8845](https://github.com/netbox-community/netbox/issues/8845) - Correct default ASN formatting in table * [#8869](https://github.com/netbox-community/netbox/issues/8869) - Fix NoReverseMatch exception when displaying tag w/assignments diff --git a/netbox/dcim/tables/devices.py b/netbox/dcim/tables/devices.py index ffa95c119..f3e1d39e0 100644 --- a/netbox/dcim/tables/devices.py +++ b/netbox/dcim/tables/devices.py @@ -772,7 +772,6 @@ class InventoryItemTable(DeviceComponentTable): linkify=True ) component = tables.Column( - accessor=Accessor('component'), orderable=False, linkify=True ) diff --git a/netbox/netbox/views/generic/object_views.py b/netbox/netbox/views/generic/object_views.py index e73a68a98..4ebfe71cc 100644 --- a/netbox/netbox/views/generic/object_views.py +++ b/netbox/netbox/views/generic/object_views.py @@ -545,7 +545,7 @@ class ComponentCreateView(GetReturnURLMixin, BaseObjectView): def get(self, request): form, model_form = self.initialize_forms(request) - instance = self.alter_object(self.queryset.model, request) + instance = self.alter_object(self.queryset.model(), request) return render(request, self.template_name, { 'object': instance, @@ -557,7 +557,7 @@ class ComponentCreateView(GetReturnURLMixin, BaseObjectView): def post(self, request): logger = logging.getLogger('netbox.views.ComponentCreateView') form, model_form = self.initialize_forms(request) - instance = self.alter_object(self.queryset.model, request) + instance = self.alter_object(self.queryset.model(), request) if form.is_valid(): new_components = [] From e575279738c65b659fe68919174c29c00816473d Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 4 Apr 2022 15:58:54 -0400 Subject: [PATCH 36/94] Changelog for #8365 --- docs/release-notes/version-3.1.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/version-3.1.md b/docs/release-notes/version-3.1.md index bab66f2ad..e3d75269a 100644 --- a/docs/release-notes/version-3.1.md +++ b/docs/release-notes/version-3.1.md @@ -5,6 +5,7 @@ ### Enhancements * [#8163](https://github.com/netbox-community/netbox/issues/8163) - Show bridge interface members under interface view +* [#8365](https://github.com/netbox-community/netbox/issues/8365) - Enable filtering child devices by parent device ID * [#8785](https://github.com/netbox-community/netbox/issues/8785) - Permit wildcard values in IP address DNS names * [#8790](https://github.com/netbox-community/netbox/issues/8790) - Include site and prefixes columns in VLAN group VLANs table * [#8830](https://github.com/netbox-community/netbox/issues/8830) - Add Checkpoint ClusterXL protocol for FHRP groups From 830b56ac9ef014b037b1a6c81c87219c69848667 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 5 Apr 2022 08:40:30 -0400 Subject: [PATCH 37/94] Check that ChoiceSet CHOICES is mutable if key is set --- netbox/utilities/choices.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/netbox/utilities/choices.py b/netbox/utilities/choices.py index 62f6837ec..c5b5bafb9 100644 --- a/netbox/utilities/choices.py +++ b/netbox/utilities/choices.py @@ -9,6 +9,7 @@ class ChoiceSetMeta(type): # Extend static choices with any configured choices if key := attrs.get('key'): + assert type(attrs['CHOICES']) is list, f"{name} has a key defined but CHOICES is not a list" app = attrs['__module__'].split('.', 1)[0] replace_key = f'{app}.{key}' extend_key = f'{replace_key}+' if replace_key else None @@ -47,7 +48,7 @@ class ChoiceSetMeta(type): class ChoiceSet(metaclass=ChoiceSetMeta): """ - Holds an interable of choice tuples suitable for passing to a Django model or form field. Choices can be defined + Holds an iterable of choice tuples suitable for passing to a Django model or form field. Choices can be defined statically within the class as CHOICES and/or gleaned from the FIELD_CHOICES configuration parameter. """ CHOICES = list() From 8b92bc6c4a782dbb83aadb1bbfc5951dc53f53e1 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 5 Apr 2022 10:07:48 -0400 Subject: [PATCH 38/94] Add migration safeguard to prevent accidental destruction of data --- .../0145_site_remove_deprecated_fields.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/netbox/dcim/migrations/0145_site_remove_deprecated_fields.py b/netbox/dcim/migrations/0145_site_remove_deprecated_fields.py index 29353107c..6de7dc4e5 100644 --- a/netbox/dcim/migrations/0145_site_remove_deprecated_fields.py +++ b/netbox/dcim/migrations/0145_site_remove_deprecated_fields.py @@ -1,4 +1,26 @@ from django.db import migrations +from django.db.utils import DataError + + +def check_legacy_data(apps, schema_editor): + """ + Abort the migration if any legacy site fields still contain data. + """ + Site = apps.get_model('dcim', 'Site') + + if site_count := Site.objects.exclude(asn__isnull=True).count(): + raise DataError( + f"Unable to proceed with deleting asn field from Site model: Found {site_count} sites with " + f"legacy ASN data. Please ensure all legacy site ASN data has been migrated to ASN objects " + f"before proceeding." + ) + + if site_count := Site.objects.exclude(contact_name='', contact_phone='', contact_email='').count(): + raise DataError( + f"Unable to proceed with deleting contact fields from Site model: Found {site_count} sites " + f"with legacy contact data. Please ensure all legacy site contact data has been migrated to " + f"contact objects before proceeding." + ) class Migration(migrations.Migration): @@ -8,6 +30,10 @@ class Migration(migrations.Migration): ] operations = [ + migrations.RunPython( + code=check_legacy_data, + reverse_code=migrations.RunPython.noop + ), migrations.RemoveField( model_name='site', name='asn', From a7fc8621a87961e2ae91b373106cf1f91b9d2df7 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 5 Apr 2022 10:18:20 -0400 Subject: [PATCH 39/94] Closes #9036: Add bulk edit capability for site contact fields --- docs/release-notes/version-3.1.md | 1 + netbox/dcim/forms/bulk_edit.py | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.1.md b/docs/release-notes/version-3.1.md index e3d75269a..3214ea002 100644 --- a/docs/release-notes/version-3.1.md +++ b/docs/release-notes/version-3.1.md @@ -11,6 +11,7 @@ * [#8830](https://github.com/netbox-community/netbox/issues/8830) - Add Checkpoint ClusterXL protocol for FHRP groups * [#8974](https://github.com/netbox-community/netbox/issues/8974) - Use monospace font for text areas in config revision form * [#9012](https://github.com/netbox-community/netbox/issues/9012) - Linkify circuits count in providers list +* [#9036](https://github.com/netbox-community/netbox/issues/9036) - Add bulk edit capability for site contact fields ### Bug Fixes diff --git a/netbox/dcim/forms/bulk_edit.py b/netbox/dcim/forms/bulk_edit.py index 3b604d79d..a48b1d8b2 100644 --- a/netbox/dcim/forms/bulk_edit.py +++ b/netbox/dcim/forms/bulk_edit.py @@ -122,6 +122,18 @@ class SiteBulkEditForm(AddRemoveTagsForm, CustomFieldModelBulkEditForm): label=_('ASNs'), required=False ) + contact_name = forms.CharField( + max_length=50, + required=False + ) + contact_phone = forms.CharField( + max_length=20, + required=False + ) + contact_email = forms.EmailField( + required=False, + label='Contact E-mail' + ) description = forms.CharField( max_length=100, required=False @@ -134,7 +146,8 @@ class SiteBulkEditForm(AddRemoveTagsForm, CustomFieldModelBulkEditForm): class Meta: nullable_fields = [ - 'region', 'group', 'tenant', 'asn', 'asns', 'description', 'time_zone', + 'region', 'group', 'tenant', 'asn', 'asns', 'contact_name', 'contact_phone', 'contact_email', 'description', + 'time_zone', ] From 0f5fe746e05f0a888fe3c823470bd6131d9349d1 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 5 Apr 2022 10:22:42 -0400 Subject: [PATCH 40/94] Add warning for legacy ASN field on site --- netbox/templates/dcim/site.html | 91 +++++++++++++++++---------------- 1 file changed, 46 insertions(+), 45 deletions(-) diff --git a/netbox/templates/dcim/site.html b/netbox/templates/dcim/site.html index aa17fd57f..cf03fbf2e 100644 --- a/netbox/templates/dcim/site.html +++ b/netbox/templates/dcim/site.html @@ -80,7 +80,14 @@ AS Number - {{ object.asn|placeholder }} + + {% if object.asn %} +
+ +
+ {% endif %} + {{ object.asn|placeholder }} + Time Zone @@ -128,50 +135,44 @@ {# Legacy contact fields #} - {% with deprecation_warning="This field will be removed in a future release. Please migrate this data to contact objects." %} - {% if object.contact_name %} - - Contact Name - - {% if object.contact_name %} -
- -
- {% endif %} - {{ object.contact_name|placeholder }} - - - {% endif %} - {% if object.contact_phone %} - - Contact Phone - - {% if object.contact_phone %} -
- -
- {{ object.contact_phone }} - {% else %} - - {% endif %} - - - {% endif %} - {% if object.contact_email %} - - Contact E-Mail - - {% if object.contact_email %} -
- -
- {{ object.contact_email }} - {% else %} - - {% endif %} - - - {% endif %} + {% with deprecation_warning="This field will be removed in NetBox v3.2. Please migrate this data to contact objects." %} + + Contact Name + + {% if object.contact_name %} +
+ +
+ {% endif %} + {{ object.contact_name|placeholder }} + + + + Contact Phone + + {% if object.contact_phone %} +
+ +
+ {{ object.contact_phone }} + {% else %} + + {% endif %} + + + + Contact E-Mail + + {% if object.contact_email %} +
+ +
+ {{ object.contact_email }} + {% else %} + + {% endif %} + + {% endwith %}
From 66464fd807b583a3605e8b65bb3f539daae33a31 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 5 Apr 2022 14:10:35 -0400 Subject: [PATCH 41/94] Implement bypass for migration safeguard --- docs/release-notes/version-3.2.md | 6 ++++++ .../0145_site_remove_deprecated_fields.py | 14 ++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index a0ba35953..f0b230edb 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -5,6 +5,12 @@ !!! warning "Python 3.8 or Later Required" NetBox v3.2 requires Python 3.8 or later. +!!! warning "Deletion of Legacy Data" + This release includes a database migration that will remove the `asn`, `contact_name`, `contact_phone`, and `contact_email` fields from the site model. (These fields have been superseded by the ASN and contact models introduced in NetBox v3.1.) To protect against the accidental destruction of data, the upgrade process **will fail** if any sites still have data in any of these fields. To bypass this safeguard, set the `NETBOX_DELETE_LEGACY_DATA` environment variable when running the upgrade script, which will permit the destruction of legacy data. + +!!! tip "Migration Scripts" + A set of [migration scripts](https://github.com/netbox-community/migration-scripts) is available to assist with the migration of legacy site data. + ### Breaking Changes * Automatic redirection of legacy slug-based URL paths has been removed. URL-based slugs were changed to use numeric IDs in v2.11.0. diff --git a/netbox/dcim/migrations/0145_site_remove_deprecated_fields.py b/netbox/dcim/migrations/0145_site_remove_deprecated_fields.py index 6de7dc4e5..86918447d 100644 --- a/netbox/dcim/migrations/0145_site_remove_deprecated_fields.py +++ b/netbox/dcim/migrations/0145_site_remove_deprecated_fields.py @@ -1,3 +1,5 @@ +import os + from django.db import migrations from django.db.utils import DataError @@ -8,18 +10,22 @@ def check_legacy_data(apps, schema_editor): """ Site = apps.get_model('dcim', 'Site') - if site_count := Site.objects.exclude(asn__isnull=True).count(): + site_count = Site.objects.exclude(asn__isnull=True).count() + if site_count and 'NETBOX_DELETE_LEGACY_DATA' not in os.environ: raise DataError( f"Unable to proceed with deleting asn field from Site model: Found {site_count} sites with " f"legacy ASN data. Please ensure all legacy site ASN data has been migrated to ASN objects " - f"before proceeding." + f"before proceeding. Or, set the NETBOX_DELETE_LEGACY_DATA environment variable to bypass " + f"this safeguard and delete all legacy site ASN data." ) - if site_count := Site.objects.exclude(contact_name='', contact_phone='', contact_email='').count(): + site_count = Site.objects.exclude(contact_name='', contact_phone='', contact_email='').count() + if site_count and 'NETBOX_DELETE_LEGACY_DATA' not in os.environ: raise DataError( f"Unable to proceed with deleting contact fields from Site model: Found {site_count} sites " f"with legacy contact data. Please ensure all legacy site contact data has been migrated to " - f"contact objects before proceeding." + f"contact objects before proceeding. Or, set the NETBOX_DELETE_LEGACY_DATA environment " + f"variable to bypass this safeguard and delete all legacy site contact data." ) From 631de20a8d09bff5adf94fa91b21375431d7820d Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 5 Apr 2022 14:35:27 -0400 Subject: [PATCH 42/94] Release v3.1.11 --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- .github/ISSUE_TEMPLATE/feature_request.yaml | 2 +- docs/release-notes/version-3.1.md | 2 +- netbox/netbox/settings.py | 2 +- requirements.txt | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 21dc72545..0757c7283 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -14,7 +14,7 @@ body: attributes: label: NetBox version description: What version of NetBox are you currently running? - placeholder: v3.1.10 + placeholder: v3.1.11 validations: required: true - type: dropdown diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index f64f5ccba..eb1e216cd 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yaml +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -14,7 +14,7 @@ body: attributes: label: NetBox version description: What version of NetBox are you currently running? - placeholder: v3.1.10 + placeholder: v3.1.11 validations: required: true - type: dropdown diff --git a/docs/release-notes/version-3.1.md b/docs/release-notes/version-3.1.md index 3214ea002..27ba4e69e 100644 --- a/docs/release-notes/version-3.1.md +++ b/docs/release-notes/version-3.1.md @@ -1,6 +1,6 @@ # NetBox v3.1 -## v3.1.11 (FUTURE) +## v3.1.11 (2022-04-05) ### Enhancements diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index decb7cea8..aee9ebc83 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -19,7 +19,7 @@ from netbox.config import PARAMS # Environment setup # -VERSION = '3.1.11-dev' +VERSION = '3.1.11' # Hostname HOSTNAME = platform.node() diff --git a/requirements.txt b/requirements.txt index b331fb17e..801902b3c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,7 +18,7 @@ gunicorn==20.1.0 Jinja2==3.0.3 Markdown==3.3.6 markdown-include==0.6.0 -mkdocs-material==8.2.7 +mkdocs-material==8.2.8 netaddr==0.8.0 Pillow==9.0.1 psycopg2-binary==2.9.3 From c1b7f09530f0293d0f053b8930539b1d174cd03b Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 5 Apr 2022 15:56:21 -0400 Subject: [PATCH 43/94] Ensure legacy data checks run before other migrations --- netbox/circuits/migrations/0032_provider_service_id.py | 1 + netbox/extras/migrations/0068_configcontext_cluster_types.py | 1 + netbox/ipam/migrations/0054_vlangroup_min_max_vids.py | 1 + netbox/tenancy/migrations/0005_standardize_id_fields.py | 1 + netbox/users/migrations/0002_standardize_id_fields.py | 1 + netbox/virtualization/migrations/0027_standardize_id_fields.py | 1 + netbox/wireless/migrations/0002_standardize_id_fields.py | 1 + 7 files changed, 7 insertions(+) diff --git a/netbox/circuits/migrations/0032_provider_service_id.py b/netbox/circuits/migrations/0032_provider_service_id.py index 91410bd96..58936d1bd 100644 --- a/netbox/circuits/migrations/0032_provider_service_id.py +++ b/netbox/circuits/migrations/0032_provider_service_id.py @@ -5,6 +5,7 @@ class Migration(migrations.Migration): dependencies = [ ('circuits', '0004_rename_cable_peer'), + ('dcim', '0145_site_remove_deprecated_fields'), ] operations = [ diff --git a/netbox/extras/migrations/0068_configcontext_cluster_types.py b/netbox/extras/migrations/0068_configcontext_cluster_types.py index abe90013e..3d314991d 100644 --- a/netbox/extras/migrations/0068_configcontext_cluster_types.py +++ b/netbox/extras/migrations/0068_configcontext_cluster_types.py @@ -4,6 +4,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ + ('dcim', '0145_site_remove_deprecated_fields'), ('virtualization', '0026_vminterface_bridge'), ('extras', '0067_customfield_min_max_values'), ] diff --git a/netbox/ipam/migrations/0054_vlangroup_min_max_vids.py b/netbox/ipam/migrations/0054_vlangroup_min_max_vids.py index adbe69f4c..7b901fe13 100644 --- a/netbox/ipam/migrations/0054_vlangroup_min_max_vids.py +++ b/netbox/ipam/migrations/0054_vlangroup_min_max_vids.py @@ -7,6 +7,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ + ('dcim', '0145_site_remove_deprecated_fields'), ('ipam', '0053_asn_model'), ] diff --git a/netbox/tenancy/migrations/0005_standardize_id_fields.py b/netbox/tenancy/migrations/0005_standardize_id_fields.py index 514478f17..05ea39066 100644 --- a/netbox/tenancy/migrations/0005_standardize_id_fields.py +++ b/netbox/tenancy/migrations/0005_standardize_id_fields.py @@ -4,6 +4,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ + ('dcim', '0145_site_remove_deprecated_fields'), ('tenancy', '0004_extend_tag_support'), ] diff --git a/netbox/users/migrations/0002_standardize_id_fields.py b/netbox/users/migrations/0002_standardize_id_fields.py index 60191d916..212ede6b1 100644 --- a/netbox/users/migrations/0002_standardize_id_fields.py +++ b/netbox/users/migrations/0002_standardize_id_fields.py @@ -4,6 +4,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ + ('dcim', '0145_site_remove_deprecated_fields'), ('users', '0001_squashed_0011'), ] diff --git a/netbox/virtualization/migrations/0027_standardize_id_fields.py b/netbox/virtualization/migrations/0027_standardize_id_fields.py index 01d7e8af1..8c5ea8d70 100644 --- a/netbox/virtualization/migrations/0027_standardize_id_fields.py +++ b/netbox/virtualization/migrations/0027_standardize_id_fields.py @@ -4,6 +4,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ + ('dcim', '0145_site_remove_deprecated_fields'), ('virtualization', '0026_vminterface_bridge'), ] diff --git a/netbox/wireless/migrations/0002_standardize_id_fields.py b/netbox/wireless/migrations/0002_standardize_id_fields.py index 9e0b202c2..d386d84fc 100644 --- a/netbox/wireless/migrations/0002_standardize_id_fields.py +++ b/netbox/wireless/migrations/0002_standardize_id_fields.py @@ -4,6 +4,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ + ('dcim', '0145_site_remove_deprecated_fields'), ('wireless', '0001_wireless'), ] From 6f0ae8a5b8306de97b26c6681ede9a86fd477298 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 5 Apr 2022 16:26:07 -0400 Subject: [PATCH 44/94] Release v3.2.0 --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- .github/ISSUE_TEMPLATE/feature_request.yaml | 2 +- base_requirements.txt | 2 +- docs/release-notes/index.md | 2 +- docs/release-notes/version-3.2.md | 2 +- netbox/netbox/settings.py | 2 +- requirements.txt | 6 +++--- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 0757c7283..ae3fe68f3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -14,7 +14,7 @@ body: attributes: label: NetBox version description: What version of NetBox are you currently running? - placeholder: v3.1.11 + placeholder: v3.2.0 validations: required: true - type: dropdown diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index eb1e216cd..1ce4c0a11 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yaml +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -14,7 +14,7 @@ body: attributes: label: NetBox version description: What version of NetBox are you currently running? - placeholder: v3.1.11 + placeholder: v3.2.0 validations: required: true - type: dropdown diff --git a/base_requirements.txt b/base_requirements.txt index 77a5bb8aa..e1cf2c54c 100644 --- a/base_requirements.txt +++ b/base_requirements.txt @@ -84,7 +84,7 @@ mkdocs-material # Introspection for embedded code # https://github.com/mkdocstrings/mkdocstrings -mkdocstrings +mkdocstrings<=0.17.0 # Library for manipulating IP prefixes and addresses # https://github.com/netaddr/netaddr diff --git a/docs/release-notes/index.md b/docs/release-notes/index.md index af15ba7b6..f8bb365be 100644 --- a/docs/release-notes/index.md +++ b/docs/release-notes/index.md @@ -10,7 +10,7 @@ Minor releases are published in April, August, and December of each calendar yea This page contains a history of all major and minor releases since NetBox v2.0. For more detail on a specific patch release, please see the release notes page for that specific minor release. -#### [Version 3.2](./version-3.2.md) (Pending Release) +#### [Version 3.2](./version-3.2.md) (April 2022) * Plugins Framework Extensions ([#8333](https://github.com/netbox-community/netbox/issues/8333)) * Modules & Module Types ([#7844](https://github.com/netbox-community/netbox/issues/7844)) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index f0b230edb..9f354dbd6 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -1,6 +1,6 @@ # NetBox v3.2 -## v3.2.0 (FUTURE) +## v3.2.0 (2022-04-05) !!! warning "Python 3.8 or Later Required" NetBox v3.2 requires Python 3.8 or later. diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 8b60e7774..1e972df8c 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -26,7 +26,7 @@ django.utils.encoding.force_text = force_str # Environment setup # -VERSION = '3.2.0-dev' +VERSION = '3.2.0' # Hostname HOSTNAME = platform.node() diff --git a/requirements.txt b/requirements.txt index 2fcf3da64..757cf4896 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,20 +15,20 @@ djangorestframework==3.13.1 drf-yasg[validation]==1.20.0 graphene-django==2.15.0 gunicorn==20.1.0 -Jinja2==3.0.3 +Jinja2==3.1.1 Markdown==3.3.6 markdown-include==0.6.0 mkdocs-material==8.2.8 mkdocstrings==0.17.0 netaddr==0.8.0 -Pillow==9.0.1 +Pillow==9.1.0 psycopg2-binary==2.9.3 PyYAML==6.0 social-auth-app-django==5.0.0 social-auth-core==4.2.0 svgwrite==1.4.2 tablib==3.2.0 -tzdata==2021.5 +tzdata==2022.1 # Workaround for #7401 jsonschema==3.2.0 From 6ee6227b67dcfd8777d40322e948fcb918e0f916 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 5 Apr 2022 16:34:15 -0400 Subject: [PATCH 45/94] Pin Jinja2 to v3.0 --- base_requirements.txt | 3 ++- requirements.txt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/base_requirements.txt b/base_requirements.txt index e1cf2c54c..4b814dbc7 100644 --- a/base_requirements.txt +++ b/base_requirements.txt @@ -68,7 +68,8 @@ gunicorn # Platform-agnostic template rendering engine # https://github.com/pallets/jinja -Jinja2 +# Pin to v3.0 for mkdocstrings +Jinja2<3.1 # Simple markup language for rendering HTML # https://github.com/Python-Markdown/markdown diff --git a/requirements.txt b/requirements.txt index 757cf4896..ce0e52087 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,7 +15,7 @@ djangorestframework==3.13.1 drf-yasg[validation]==1.20.0 graphene-django==2.15.0 gunicorn==20.1.0 -Jinja2==3.1.1 +Jinja2==3.0.3 Markdown==3.3.6 markdown-include==0.6.0 mkdocs-material==8.2.8 From ea197eff5f4fe925bb354d1375912decd81752bd Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 5 Apr 2022 17:12:13 -0400 Subject: [PATCH 46/94] PRVB --- docs/release-notes/version-3.2.md | 4 ++++ netbox/netbox/settings.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index 9f354dbd6..ddf2ebded 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -1,5 +1,9 @@ # NetBox v3.2 +## v3.2.1 (FUTURE) + +--- + ## v3.2.0 (2022-04-05) !!! warning "Python 3.8 or Later Required" diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 1e972df8c..04c0e9c3d 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -26,7 +26,7 @@ django.utils.encoding.force_text = force_str # Environment setup # -VERSION = '3.2.0' +VERSION = '3.2.1-dev' # Hostname HOSTNAME = platform.node() From 523390cd8e989b49f59a757695e585a923ae199f Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Wed, 6 Apr 2022 13:35:22 -0500 Subject: [PATCH 47/94] #9061 - Change inheritance order for DeviceComponentFilterSets --- docs/release-notes/version-3.2.md | 5 +++++ netbox/dcim/filtersets.py | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index ddf2ebded..cdb319e98 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -2,6 +2,11 @@ ## v3.2.1 (FUTURE) +### Bug Fixes (From Beta2) + +* [#9061](https://github.com/netbox-community/netbox/issues/9061) - Change inheritance order for DeviceComponentFilterSets + + --- ## v3.2.0 (2022-04-05) diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py index a380fbcce..0f4e7cf7e 100644 --- a/netbox/dcim/filtersets.py +++ b/netbox/dcim/filtersets.py @@ -1095,8 +1095,8 @@ class PathEndpointFilterSet(django_filters.FilterSet): class ConsolePortFilterSet( - NetBoxModelFilterSet, ModularDeviceComponentFilterSet, + NetBoxModelFilterSet, CableTerminationFilterSet, PathEndpointFilterSet ): @@ -1111,8 +1111,8 @@ class ConsolePortFilterSet( class ConsoleServerPortFilterSet( - NetBoxModelFilterSet, ModularDeviceComponentFilterSet, + NetBoxModelFilterSet, CableTerminationFilterSet, PathEndpointFilterSet ): @@ -1127,8 +1127,8 @@ class ConsoleServerPortFilterSet( class PowerPortFilterSet( - NetBoxModelFilterSet, ModularDeviceComponentFilterSet, + NetBoxModelFilterSet, CableTerminationFilterSet, PathEndpointFilterSet ): @@ -1143,8 +1143,8 @@ class PowerPortFilterSet( class PowerOutletFilterSet( - NetBoxModelFilterSet, ModularDeviceComponentFilterSet, + NetBoxModelFilterSet, CableTerminationFilterSet, PathEndpointFilterSet ): @@ -1163,8 +1163,8 @@ class PowerOutletFilterSet( class InterfaceFilterSet( - NetBoxModelFilterSet, ModularDeviceComponentFilterSet, + NetBoxModelFilterSet, CableTerminationFilterSet, PathEndpointFilterSet ): @@ -1291,8 +1291,8 @@ class InterfaceFilterSet( class FrontPortFilterSet( - NetBoxModelFilterSet, ModularDeviceComponentFilterSet, + NetBoxModelFilterSet, CableTerminationFilterSet ): type = django_filters.MultipleChoiceFilter( @@ -1306,8 +1306,8 @@ class FrontPortFilterSet( class RearPortFilterSet( - NetBoxModelFilterSet, ModularDeviceComponentFilterSet, + NetBoxModelFilterSet, CableTerminationFilterSet ): type = django_filters.MultipleChoiceFilter( @@ -1320,21 +1320,21 @@ class RearPortFilterSet( fields = ['id', 'name', 'label', 'type', 'color', 'positions', 'description'] -class ModuleBayFilterSet(NetBoxModelFilterSet, DeviceComponentFilterSet): +class ModuleBayFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet): class Meta: model = ModuleBay fields = ['id', 'name', 'label', 'description'] -class DeviceBayFilterSet(NetBoxModelFilterSet, DeviceComponentFilterSet): +class DeviceBayFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet): class Meta: model = DeviceBay fields = ['id', 'name', 'label', 'description'] -class InventoryItemFilterSet(NetBoxModelFilterSet, DeviceComponentFilterSet): +class InventoryItemFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet): parent_id = django_filters.ModelMultipleChoiceFilter( queryset=InventoryItem.objects.all(), label='Parent inventory item (ID)', From 85e65edb7d98c07f857dcb20f87359a8c81a82a2 Mon Sep 17 00:00:00 2001 From: Daniel Sheppard Date: Wed, 6 Apr 2022 13:46:31 -0500 Subject: [PATCH 48/94] Fixes #9057 - Fix missing instance counts for module types --- docs/release-notes/version-3.2.md | 1 + netbox/dcim/views.py | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index cdb319e98..6fe4ed851 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -4,6 +4,7 @@ ### Bug Fixes (From Beta2) +* [#9057](https://github.com/netbox-community/netbox/issues/9057) - Fix missing instance counts for module types * [#9061](https://github.com/netbox-community/netbox/issues/9061) - Change inheritance order for DeviceComponentFilterSets diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 4157fd2e9..e60e6abc8 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -960,7 +960,7 @@ class DeviceTypeBulkDeleteView(generic.BulkDeleteView): class ModuleTypeListView(generic.ObjectListView): queryset = ModuleType.objects.prefetch_related('manufacturer').annotate( - # instance_count=count_related(Module, 'module_type') + instance_count=count_related(Module, 'module_type') ) filterset = filtersets.ModuleTypeFilterSet filterset_form = forms.ModuleTypeFilterForm @@ -1066,7 +1066,7 @@ class ModuleTypeImportView(generic.ObjectImportView): class ModuleTypeBulkEditView(generic.BulkEditView): queryset = ModuleType.objects.prefetch_related('manufacturer').annotate( - # instance_count=count_related(Module, 'module_type') + instance_count=count_related(Module, 'module_type') ) filterset = filtersets.ModuleTypeFilterSet table = tables.ModuleTypeTable @@ -1075,7 +1075,7 @@ class ModuleTypeBulkEditView(generic.BulkEditView): class ModuleTypeBulkDeleteView(generic.BulkDeleteView): queryset = ModuleType.objects.prefetch_related('manufacturer').annotate( - # instance_count=count_related(Module, 'module_type') + instance_count=count_related(Module, 'module_type') ) filterset = filtersets.ModuleTypeFilterSet table = tables.ModuleTypeTable From 6760533a101a9ecf048d19f0cab96264e8324c05 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 6 Apr 2022 20:01:09 -0400 Subject: [PATCH 49/94] Fixes #8931: Copy assigned tenant when cloning a location --- docs/release-notes/version-3.2.md | 4 ++-- netbox/dcim/models/sites.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index 6fe4ed851..4740d0e0c 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -2,12 +2,12 @@ ## v3.2.1 (FUTURE) -### Bug Fixes (From Beta2) +### Bug Fixes +* [#8931](https://github.com/netbox-community/netbox/issues/8931) - Copy assigned tenant when cloning a location * [#9057](https://github.com/netbox-community/netbox/issues/9057) - Fix missing instance counts for module types * [#9061](https://github.com/netbox-community/netbox/issues/9061) - Change inheritance order for DeviceComponentFilterSets - --- ## v3.2.0 (2022-04-05) diff --git a/netbox/dcim/models/sites.py b/netbox/dcim/models/sites.py index 53e3bcceb..d02bd0932 100644 --- a/netbox/dcim/models/sites.py +++ b/netbox/dcim/models/sites.py @@ -367,7 +367,7 @@ class Location(NestedGroupModel): to='extras.ImageAttachment' ) - clone_fields = ['site', 'parent', 'description'] + clone_fields = ['site', 'parent', 'tenant', 'description'] class Meta: ordering = ['site', 'name'] From d93e944c07a1f045514f973cb9d8a84dccc1e70e Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 6 Apr 2022 20:12:14 -0400 Subject: [PATCH 50/94] Closes #8973: Display VLAN group count under site view --- docs/release-notes/version-3.2.md | 4 ++++ netbox/dcim/views.py | 6 +++++- netbox/templates/dcim/site.html | 10 ++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index 4740d0e0c..90f339111 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -2,6 +2,10 @@ ## v3.2.1 (FUTURE) +### Enhancements + +* [#8973](https://github.com/netbox-community/netbox/issues/8973) - Display VLAN group count under site view + ### Bug Fixes * [#8931](https://github.com/netbox-community/netbox/issues/8931) - Copy assigned tenant when cloning a location diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index e60e6abc8..c0b46f16e 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -14,7 +14,7 @@ from django.views.generic import View from circuits.models import Circuit from extras.views import ObjectConfigContextView -from ipam.models import ASN, IPAddress, Prefix, Service, VLAN +from ipam.models import ASN, IPAddress, Prefix, Service, VLAN, VLANGroup from ipam.tables import AssignedIPAddressesTable, InterfaceVLANTable from netbox.views import generic from utilities.forms import ConfirmationForm @@ -320,6 +320,10 @@ class SiteView(generic.ObjectView): 'rack_count': Rack.objects.restrict(request.user, 'view').filter(site=instance).count(), 'device_count': Device.objects.restrict(request.user, 'view').filter(site=instance).count(), 'prefix_count': Prefix.objects.restrict(request.user, 'view').filter(site=instance).count(), + 'vlangroup_count': VLANGroup.objects.restrict(request.user, 'view').filter( + scope_type=ContentType.objects.get_for_model(Site), + 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(), 'vm_count': VirtualMachine.objects.restrict(request.user, 'view').filter(cluster__site=instance).count(), diff --git a/netbox/templates/dcim/site.html b/netbox/templates/dcim/site.html index fe0a558eb..c15cab468 100644 --- a/netbox/templates/dcim/site.html +++ b/netbox/templates/dcim/site.html @@ -188,6 +188,16 @@ {% endif %} + + VLAN Groups + + {% if stats.vlangroup_count %} + {{ stats.vlangroup_count }} + {% else %} + {{ ''|placeholder }} + {% endif %} + + VLANs From f4e78b0ea6e0db8d6c07cdb0e6adfcaddcd542f4 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 6 Apr 2022 20:29:28 -0400 Subject: [PATCH 51/94] Fixes #9065: Min/max VID should not be required when filtering VLAN groups --- docs/release-notes/version-3.2.md | 1 + netbox/ipam/forms/filtersets.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index 90f339111..1d2516cdf 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -11,6 +11,7 @@ * [#8931](https://github.com/netbox-community/netbox/issues/8931) - Copy assigned tenant when cloning a location * [#9057](https://github.com/netbox-community/netbox/issues/9057) - Fix missing instance counts for module types * [#9061](https://github.com/netbox-community/netbox/issues/9061) - Change inheritance order for DeviceComponentFilterSets +* [#9065](https://github.com/netbox-community/netbox/issues/9065) - Min/max VID should not be required when filtering VLAN groups --- diff --git a/netbox/ipam/forms/filtersets.py b/netbox/ipam/forms/filtersets.py index 57f39f8c2..bbd6bb97b 100644 --- a/netbox/ipam/forms/filtersets.py +++ b/netbox/ipam/forms/filtersets.py @@ -377,12 +377,16 @@ class VLANGroupFilterForm(NetBoxModelFilterSetForm): label=_('Rack') ) min_vid = forms.IntegerField( + required=False, min_value=VLAN_VID_MIN, max_value=VLAN_VID_MAX, + label='Minimum VID' ) max_vid = forms.IntegerField( + required=False, min_value=VLAN_VID_MIN, max_value=VLAN_VID_MAX, + label='Maximum VID' ) tag = TagFilterField(model) From b9f6a5625f221ede86b022dd30abebe373209676 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 6 Apr 2022 20:30:29 -0400 Subject: [PATCH 52/94] Update supported Python versions --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index ae3fe68f3..65097e9be 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -22,9 +22,9 @@ body: label: Python version description: What version of Python are you currently running? options: - - "3.7" - "3.8" - "3.9" + - "3.10" validations: required: true - type: textarea From c3d9910e082f5878a9312c0ee18cadd5b7f8a671 Mon Sep 17 00:00:00 2001 From: Jason Yates Date: Thu, 7 Apr 2022 08:21:13 +0100 Subject: [PATCH 53/94] Limit amount of nonracked devices displayed Fixes #8920 Limits the amount of non-racked devices on Site and Location view to 10 and provides a link to the device list this is pre-filtered to the relevant site or location. --- netbox/dcim/views.py | 18 ++++- .../templates/dcim/inc/nonracked_devices.html | 68 +++++++++++-------- 2 files changed, 57 insertions(+), 29 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index c0b46f16e..9b24ea9d1 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -346,7 +346,13 @@ class SiteView(generic.ObjectView): site=instance, position__isnull=True, parent_bay__isnull=True - ).prefetch_related('device_type__manufacturer') + ).prefetch_related('device_type__manufacturer').order_by('-pk')[:10] + + total_nonracked_devices_count = Device.objects.filter( + site=instance, + position__isnull=True, + parent_bay__isnull=True + ).count() asns = ASN.objects.restrict(request.user, 'view').filter(sites=instance) asn_count = asns.count() @@ -358,6 +364,7 @@ class SiteView(generic.ObjectView): 'locations': locations, 'asns': asns, 'nonracked_devices': nonracked_devices, + 'total_nonracked_devices_count': total_nonracked_devices_count, } @@ -439,13 +446,20 @@ class LocationView(generic.ObjectView): location=instance, position__isnull=True, parent_bay__isnull=True - ).prefetch_related('device_type__manufacturer') + ).prefetch_related('device_type__manufacturer').order_by('-pk')[:10] + + total_nonracked_devices_count = Device.objects.filter( + location=instance, + position__isnull=True, + parent_bay__isnull=True + ).count() return { 'rack_count': rack_count, 'device_count': device_count, 'child_locations_table': child_locations_table, 'nonracked_devices': nonracked_devices, + 'total_nonracked_devices_count': total_nonracked_devices_count, } diff --git a/netbox/templates/dcim/inc/nonracked_devices.html b/netbox/templates/dcim/inc/nonracked_devices.html index 7f4da2f24..68112e2a7 100644 --- a/netbox/templates/dcim/inc/nonracked_devices.html +++ b/netbox/templates/dcim/inc/nonracked_devices.html @@ -1,40 +1,54 @@ {% load helpers %}
-
- Non-Racked Devices -
-
-{% if nonracked_devices %} - - - - - - - - {% for device in nonracked_devices %} - - - - - {% if device.parent_bay %} - - - {% else %} - +
+ Non-Racked Devices +
+
+ {% if nonracked_devices %} +
NameRoleTypeParent Device
- {{ device }} - {{ device.device_role }}{{ device.device_type }}{{ device.parent_bay.device|linkify }}{{ device.parent_bay }}
+ + + + + + + {% for device in nonracked_devices %} + + + + + {% if device.parent_bay %} + + + {% else %} + + {% endif %} + + {% endfor %} +
NameRoleTypeParent Device
+ {{ device }} + {{ device.device_role }}{{ device.device_type }}{{ device.parent_bay.device|linkify }}{{ device.parent_bay }}
+ + {% if nonracked_devices.count == 10 %} + {% if object|meta:'verbose_name' == 'site' %} +
+ Displaying 10 of {{ total_nonracked_devices_count }} devices (View full list) +
+ {% elif object|meta:'verbose_name' == 'location' %} +
+ Displaying 10 of {{ total_nonracked_devices_count }} devices (View full list) +
{% endif %} - - {% endfor %} - + {% endif %} + {% else %}
None
{% endif %}
+ {% if perms.dcim.add_device %} {% if object|meta:'verbose_name' == 'rack' %} - {# TODO: Improve the design & layout #} {% if auth_backends %} -
Or use an SSO provider:
- {% for name, backend in auth_backends.items %} -

{{ name }}

+
Or use a single sign-on (SSO) provider:
+ {% for name, display in auth_backends.items %} +
+ {% if display.1 %}{% endif %} + {{ display.0 }} +
{% endfor %} {% endif %} diff --git a/netbox/users/views.py b/netbox/users/views.py index 04c0c5155..6a923e77e 100644 --- a/netbox/users/views.py +++ b/netbox/users/views.py @@ -16,6 +16,7 @@ from social_core.backends.utils import load_backends from extras.models import ObjectChange from extras.tables import ObjectChangeTable +from netbox.authentication import get_auth_backend_display from netbox.config import get_config from utilities.forms import ConfirmationForm from .forms import LoginForm, PasswordChangeForm, TokenForm, UserConfigForm @@ -43,9 +44,13 @@ class LoginView(View): logger = logging.getLogger('netbox.auth.login') return self.redirect_to_next(request, logger) + auth_backends = { + name: get_auth_backend_display(name) for name in load_backends(settings.AUTHENTICATION_BACKENDS).keys() + } + return render(request, self.template_name, { 'form': form, - 'auth_backends': load_backends(settings.AUTHENTICATION_BACKENDS), + 'auth_backends': auth_backends, }) def post(self, request): From fa5cf665ce7e36a5a8abd6c43b558365f3c4fe41 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 14 Apr 2022 11:13:04 -0400 Subject: [PATCH 79/94] Fixes #9128: Resolve component labels per module bay position when installing modules --- docs/release-notes/version-3.2.md | 1 + .../dcim/models/device_component_templates.py | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index 33cfd140d..e73c3048e 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -26,6 +26,7 @@ * [#9100](https://github.com/netbox-community/netbox/issues/9100) - Include position field in module type YAML export * [#9116](https://github.com/netbox-community/netbox/issues/9116) - `assigned_to_interface` filter for IP addresses should not match FHRP group assignments * [#9118](https://github.com/netbox-community/netbox/issues/9118) - Fix validation error when importing VM child interfaces +* [#9128](https://github.com/netbox-community/netbox/issues/9128) - Resolve component labels per module bay position when installing modules --- diff --git a/netbox/dcim/models/device_component_templates.py b/netbox/dcim/models/device_component_templates.py index b363d6ea4..647abe148 100644 --- a/netbox/dcim/models/device_component_templates.py +++ b/netbox/dcim/models/device_component_templates.py @@ -124,6 +124,11 @@ class ModularComponentTemplateModel(ComponentTemplateModel): return self.name.replace('{module}', module.module_bay.position) return self.name + def resolve_label(self, module): + if module: + return self.label.replace('{module}', module.module_bay.position) + return self.label + class ConsolePortTemplate(ModularComponentTemplateModel): """ @@ -147,7 +152,7 @@ class ConsolePortTemplate(ModularComponentTemplateModel): def instantiate(self, **kwargs): return self.component_model( name=self.resolve_name(kwargs.get('module')), - label=self.label, + label=self.resolve_label(kwargs.get('module')), type=self.type, **kwargs ) @@ -175,7 +180,7 @@ class ConsoleServerPortTemplate(ModularComponentTemplateModel): def instantiate(self, **kwargs): return self.component_model( name=self.resolve_name(kwargs.get('module')), - label=self.label, + label=self.resolve_label(kwargs.get('module')), type=self.type, **kwargs ) @@ -215,7 +220,7 @@ class PowerPortTemplate(ModularComponentTemplateModel): def instantiate(self, **kwargs): return self.component_model( name=self.resolve_name(kwargs.get('module')), - label=self.label, + label=self.resolve_label(kwargs.get('module')), type=self.type, maximum_draw=self.maximum_draw, allocated_draw=self.allocated_draw, @@ -286,7 +291,7 @@ class PowerOutletTemplate(ModularComponentTemplateModel): power_port = None return self.component_model( name=self.resolve_name(kwargs.get('module')), - label=self.label, + label=self.resolve_label(kwargs.get('module')), type=self.type, power_port=power_port, feed_leg=self.feed_leg, @@ -326,7 +331,7 @@ class InterfaceTemplate(ModularComponentTemplateModel): def instantiate(self, **kwargs): return self.component_model( name=self.resolve_name(kwargs.get('module')), - label=self.label, + label=self.resolve_label(kwargs.get('module')), type=self.type, mgmt_only=self.mgmt_only, **kwargs @@ -397,7 +402,7 @@ class FrontPortTemplate(ModularComponentTemplateModel): rear_port = None return self.component_model( name=self.resolve_name(kwargs.get('module')), - label=self.label, + label=self.resolve_label(kwargs.get('module')), type=self.type, color=self.color, rear_port=rear_port, @@ -437,7 +442,7 @@ class RearPortTemplate(ModularComponentTemplateModel): def instantiate(self, **kwargs): return self.component_model( name=self.resolve_name(kwargs.get('module')), - label=self.label, + label=self.resolve_label(kwargs.get('module')), type=self.type, color=self.color, positions=self.positions, From fdc018d8096355f87615318c6ab2b611777eebed Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 14 Apr 2022 13:58:18 -0400 Subject: [PATCH 80/94] Release v3.2.1 --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- .github/ISSUE_TEMPLATE/feature_request.yaml | 2 +- docs/release-notes/version-3.2.md | 2 +- netbox/netbox/settings.py | 2 +- requirements.txt | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 65097e9be..b5de9bfee 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -14,7 +14,7 @@ body: attributes: label: NetBox version description: What version of NetBox are you currently running? - placeholder: v3.2.0 + placeholder: v3.2.1 validations: required: true - type: dropdown diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index 1ce4c0a11..138e0f9b4 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yaml +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -14,7 +14,7 @@ body: attributes: label: NetBox version description: What version of NetBox are you currently running? - placeholder: v3.2.0 + placeholder: v3.2.1 validations: required: true - type: dropdown diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index e73c3048e..cd19a6d65 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -1,6 +1,6 @@ # NetBox v3.2 -## v3.2.1 (FUTURE) +## v3.2.1 (2022-04-14) ### Enhancements diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 04c0e9c3d..4e3017d8d 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -26,7 +26,7 @@ django.utils.encoding.force_text = force_str # Environment setup # -VERSION = '3.2.1-dev' +VERSION = '3.2.1' # Hostname HOSTNAME = platform.node() diff --git a/requirements.txt b/requirements.txt index ce0e52087..35867410b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Django==4.0.3 +Django==4.0.4 django-cors-headers==3.11.0 django-debug-toolbar==3.2.4 django-filter==21.1 @@ -18,7 +18,7 @@ gunicorn==20.1.0 Jinja2==3.0.3 Markdown==3.3.6 markdown-include==0.6.0 -mkdocs-material==8.2.8 +mkdocs-material==8.2.9 mkdocstrings==0.17.0 netaddr==0.8.0 Pillow==9.1.0 @@ -27,7 +27,7 @@ PyYAML==6.0 social-auth-app-django==5.0.0 social-auth-core==4.2.0 svgwrite==1.4.2 -tablib==3.2.0 +tablib==3.2.1 tzdata==2022.1 # Workaround for #7401 From 996221147e05376dae46bd86654a70161bffc859 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 14 Apr 2022 14:15:48 -0400 Subject: [PATCH 81/94] PRVB --- docs/release-notes/version-3.2.md | 4 ++++ netbox/netbox/settings.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index cd19a6d65..e1d68a093 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -1,5 +1,9 @@ # NetBox v3.2 +## v3.2.2 (FUTURE) + +--- + ## v3.2.1 (2022-04-14) ### Enhancements diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 4e3017d8d..e83ccdc73 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -26,7 +26,7 @@ django.utils.encoding.force_text = force_str # Environment setup # -VERSION = '3.2.1' +VERSION = '3.2.2-dev' # Hostname HOSTNAME = platform.node() From 7463c40c400285d74feacd77633db9295204641b Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 14 Apr 2022 14:24:34 -0400 Subject: [PATCH 82/94] Restore documentation search function --- mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs.yml b/mkdocs.yml index 3af855d3b..88bd229f2 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -19,6 +19,7 @@ theme: icon: material/lightbulb name: Switch to Light Mode plugins: + - search - mkdocstrings: handlers: python: From 7779b66972332a1e32425b0049288758a3417b33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markku=20Leini=C3=B6?= Date: Thu, 14 Apr 2022 22:01:21 +0300 Subject: [PATCH 83/94] Require Python 3.8+ to run upgrade.sh --- upgrade.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/upgrade.sh b/upgrade.sh index 301225958..61e6106cd 100755 --- a/upgrade.sh +++ b/upgrade.sh @@ -3,23 +3,23 @@ # its most recent release. # This script will invoke Python with the value of the PYTHON environment -# variable (if set), or fall back to "python3". Note that NetBox v3.0+ requires -# Python 3.7 or later. +# variable (if set), or fall back to "python3". Note that NetBox v3.2+ requires +# Python 3.8 or later. cd "$(dirname "$0")" VIRTUALENV="$(pwd -P)/venv" PYTHON="${PYTHON:-python3}" # Validate the minimum required Python version -COMMAND="${PYTHON} -c 'import sys; exit(1 if sys.version_info < (3, 7) else 0)'" +COMMAND="${PYTHON} -c 'import sys; exit(1 if sys.version_info < (3, 8) else 0)'" PYTHON_VERSION=$(eval "${PYTHON} -V") eval $COMMAND || { echo "--------------------------------------------------------------------" echo "ERROR: Unsupported Python version: ${PYTHON_VERSION}. NetBox requires" - echo "Python 3.7 or later. To specify an alternate Python executable, set" + echo "Python 3.8 or later. To specify an alternate Python executable, set" echo "the PYTHON environment variable. For example:" echo "" - echo " sudo PYTHON=/usr/bin/python3.7 ./upgrade.sh" + echo " sudo PYTHON=/usr/bin/python3.8 ./upgrade.sh" echo "" echo "To show your current Python version: ${PYTHON} -V" echo "--------------------------------------------------------------------" From 7be0a1a55f75c0b885702c6c9c65ec5727f76245 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 14 Apr 2022 15:51:26 -0400 Subject: [PATCH 84/94] Changelog for #9133 --- docs/release-notes/version-3.2.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index e1d68a093..97cedf0f5 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -2,6 +2,10 @@ ## v3.2.2 (FUTURE) +### Bug Fixes + +* [#9133](https://github.com/netbox-community/netbox/issues/9133) - Upgrade script should require Python 3.8 or later + --- ## v3.2.1 (2022-04-14) From 10c7fdb6184ff544ef35475359c35a457203c109 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 14 Apr 2022 21:41:43 -0400 Subject: [PATCH 85/94] Closes #9136: Add SSO configuration guide for Microsoft Azure AD --- .../authentication/microsoft-azure-ad.md | 79 ++++++++++++++++++ .../overview.md} | 4 +- .../azure_ad_add_app_registration.png | Bin 0 -> 11227 bytes .../azure_ad_add_client_secret.png | Bin 0 -> 17922 bytes .../azure_ad_app_registration.png | Bin 0 -> 55210 bytes .../azure_ad_app_registration_created.png | Bin 0 -> 21150 bytes .../authentication/azure_ad_client_secret.png | Bin 0 -> 8697 bytes .../azure_ad_client_secret_created.png | Bin 0 -> 21621 bytes .../authentication/azure_ad_login_portal.png | Bin 0 -> 25261 bytes .../authentication/netbox_azure_ad_login.png | Bin 0 -> 17925 bytes mkdocs.yml | 4 +- 11 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 docs/administration/authentication/microsoft-azure-ad.md rename docs/administration/{authentication.md => authentication/overview.md} (91%) create mode 100644 docs/media/authentication/azure_ad_add_app_registration.png create mode 100644 docs/media/authentication/azure_ad_add_client_secret.png create mode 100644 docs/media/authentication/azure_ad_app_registration.png create mode 100644 docs/media/authentication/azure_ad_app_registration_created.png create mode 100644 docs/media/authentication/azure_ad_client_secret.png create mode 100644 docs/media/authentication/azure_ad_client_secret_created.png create mode 100644 docs/media/authentication/azure_ad_login_portal.png create mode 100644 docs/media/authentication/netbox_azure_ad_login.png diff --git a/docs/administration/authentication/microsoft-azure-ad.md b/docs/administration/authentication/microsoft-azure-ad.md new file mode 100644 index 000000000..b2de148ac --- /dev/null +++ b/docs/administration/authentication/microsoft-azure-ad.md @@ -0,0 +1,79 @@ +# Microsoft Azure AD + +This guide explains how to configure single sign-on (SSO) support for NetBox using [Microsoft Azure Active Directory (AD)](https://azure.microsoft.com/en-us/services/active-directory/) as an authentication backend. + +## Azure AD Configuration + +### 1. Create a test user (optional) + +Create a new user in AD to be used for testing. You can skip this step if you already have a suitable account created. + +### 2. Create an app registration + +Under the Azure Active Directory dashboard, navigate to **Add > App registration**. + +![Add an app registration](../../media/authentication/azure_ad_add_app_registration.png) + +Enter a name for the registration (e.g. "NetBox") and ensure that the "single tenant" option is selected. + +Under "Redirect URI", select "Web" for the platform and enter the path to your NetBox installation, ending with `/oauth/complete/azuread-oauth2/`. Note that this URI **must** begin with `https://` unless you are referencing localhost (for development purposes). + +![App registration parameters](../../media/authentication/azure_ad_app_registration.png) + +Once finished, make note of the application (client) ID; this will be used when configuring NetBox. + +![Completed app registration](../../media/authentication/azure_ad_app_registration_created.png) + +!!! tip "Multitenant authentication" + NetBox also supports multitenant authentication via Azure AD, however it requires a different backend and an additional configuration parameter. Please see the [`python-social-auth` documentation](https://python-social-auth.readthedocs.io/en/latest/backends/azuread.html#tenant-support) for details concerning multitenant authentication. + +### 3. Create a secret + +When viewing the newly-created app registration, click the "Add a certificate or secret" link under "Client credentials". Under the "Client secrets" tab, click the "New client secret" button. + +![Add a client secret](../../media/authentication/azure_ad_add_client_secret.png) + +You can optionally specify a description and select a lifetime for the secret. + +![Client secret parameters](../../media/authentication/azure_ad_client_secret.png) + +Once finished, make note of the secret value (not the secret ID); this will be used when configuring NetBox. + +![Client secret parameters](../../media/authentication/azure_ad_client_secret_created.png) + +## NetBox Configuration + +### 1. Enter configuration parameters + +Enter the following configuration parameters in `configuration.py`, substituting your own values: + +```python +REMOTE_AUTH_BACKEND = 'social_core.backends.azuread.AzureADOAuth2' +SOCIAL_AUTH_AZUREAD_OAUTH2_KEY = '{APPLICATION_ID}' +SOCIAL_AUTH_AZUREAD_OAUTH2_SECRET = '{SECRET_VALUE}' +``` + +### 2. Restart NetBox + +Restart the NetBox services so that the new configuration takes effect. This is typically done with the command below: + +```no-highlight +sudo systemctl restart netbox +``` + +## Testing + +Log out of NetBox if already authenticated, and click the "Log In" button at top right. You should see the normal login form as well as an option to authenticate using Azure AD. Click that link. + +![NetBox Azure AD login form](../../media/authentication/netbox_azure_ad_login.png) + +You should be redirected to Microsoft's authentication portal. Enter the username/email and password of your test account to continue. You may also be prompted to grant this application access to your account. + +![NetBox Azure AD login form](../../media/authentication/azure_ad_login_portal.png) + +If successful, you will be redirected back to the NetBox UI, and will be logged in as the AD user. You can verify this by navigating to your profile (using the button at top right). + +This user account has been replicated locally to NetBox, and can now be assigned groups and permissions within the NetBox admin UI. + +!!! note "Troubleshooting" + If you are redirected to the NetBox UI after authenticating, but are _not_ logged in, double-check the configured backend and app registration. The instructions in this guide pertain only to the `azuread.AzureADOAuth2` backend using a single-tenant app registration. diff --git a/docs/administration/authentication.md b/docs/administration/authentication/overview.md similarity index 91% rename from docs/administration/authentication.md rename to docs/administration/authentication/overview.md index 31983be0b..b405ed09a 100644 --- a/docs/administration/authentication.md +++ b/docs/administration/authentication/overview.md @@ -4,7 +4,7 @@ Local user accounts and groups can be created in NetBox under the "Authentication and Authorization" section of the administrative user interface. This interface is available only to users with the "staff" permission enabled. -At a minimum, each user account must have a username and password set. User accounts may also denote a first name, last name, and email address. [Permissions](./permissions.md) may also be assigned to users and/or groups within the admin UI. +At a minimum, each user account must have a username and password set. User accounts may also denote a first name, last name, and email address. [Permissions](../permissions.md) may also be assigned to users and/or groups within the admin UI. ## Remote Authentication @@ -16,7 +16,7 @@ NetBox may be configured to provide user authenticate via a remote backend in ad REMOTE_AUTH_BACKEND = 'netbox.authentication.LDAPBackend' ``` -NetBox includes an authentication backend which supports LDAP. See the [LDAP installation docs](../installation/6-ldap.md) for more detail about this backend. +NetBox includes an authentication backend which supports LDAP. See the [LDAP installation docs](../../installation/6-ldap.md) for more detail about this backend. ### HTTP Header Authentication diff --git a/docs/media/authentication/azure_ad_add_app_registration.png b/docs/media/authentication/azure_ad_add_app_registration.png new file mode 100644 index 0000000000000000000000000000000000000000..4cc4fc81e49cfdf103d2cff21ad0a3469966620b GIT binary patch literal 11227 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 Y@@4R4UDUo44DFIA$t%m{${0WUFBY^(9{>OV literal 0 HcmV?d00001 diff --git a/docs/media/authentication/azure_ad_add_client_secret.png b/docs/media/authentication/azure_ad_add_client_secret.png new file mode 100644 index 0000000000000000000000000000000000000000..93f4eb776bcce074ed90df4c5c05fa6d21e032e4 GIT binary patch literal 17922 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 ap4YlwRf-aL5#Q~?apsh|Qp(9|_x}g`@0I%i literal 0 HcmV?d00001 diff --git a/docs/media/authentication/azure_ad_app_registration.png b/docs/media/authentication/azure_ad_app_registration.png new file mode 100644 index 0000000000000000000000000000000000000000..eb1634e96bce8c75fd932b421b01c486c0a17874 GIT binary patch literal 55210 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 literal 0 HcmV?d00001 diff --git a/docs/media/authentication/azure_ad_client_secret.png b/docs/media/authentication/azure_ad_client_secret.png new file mode 100644 index 0000000000000000000000000000000000000000..bebae388b4a99fd463a67c058785414a6603fd2e GIT binary patch literal 8697 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 EKrVXfKE(HLV%rIo*J+sj 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 XU|#bTZLZ+oyFk=c9xInBTD|)pO`#c% literal 0 HcmV?d00001 diff --git a/mkdocs.yml b/mkdocs.yml index 88bd229f2..7db4d24d7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -118,7 +118,9 @@ nav: - GraphQL API: 'plugins/development/graphql-api.md' - Background Tasks: 'plugins/development/background-tasks.md' - Administration: - - Authentication: 'administration/authentication.md' + - Authentication: + - Overview: 'administration/authentication/overview.md' + - Microsoft Azure AD: 'administration/authentication/microsoft-azure-ad.md' - Permissions: 'administration/permissions.md' - Housekeeping: 'administration/housekeeping.md' - Replicating NetBox: 'administration/replicating-netbox.md' From a889b3a4be06ea44522b1fbf2476b213128f20a5 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Fri, 15 Apr 2022 15:04:44 -0400 Subject: [PATCH 86/94] Add title for missing okta-openidconnect backend --- netbox/netbox/authentication.py | 1 + 1 file changed, 1 insertion(+) diff --git a/netbox/netbox/authentication.py b/netbox/netbox/authentication.py index 6367d6d70..a13e8d192 100644 --- a/netbox/netbox/authentication.py +++ b/netbox/netbox/authentication.py @@ -39,6 +39,7 @@ AUTH_BACKEND_ATTRS = { 'keycloak': ('Keycloak', None), 'microsoft-graph': ('Microsoft Graph', 'microsoft'), 'okta': ('Okta', None), + 'okta-openidconnect': ('Okta (OIDC)', None), 'salesforce-oauth2': ('Salesforce', 'salesforce'), } From c21db0ff6ad768a8bf232b3f1769b69d861b87a4 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Fri, 15 Apr 2022 16:03:36 -0400 Subject: [PATCH 87/94] Closes #9137: Add SSO configuration guide for Okta --- docs/administration/authentication/okta.md | 70 ++++++++++++++++++ .../authentication/netbox_okta_login.png | Bin 0 -> 16859 bytes .../okta_create_app_registration.png | Bin 0 -> 102336 bytes .../okta_integration_parameters.png | Bin 0 -> 39346 bytes .../authentication/okta_login_portal.png | Bin 0 -> 12277 bytes .../okta_web_app_integration.png | Bin 0 -> 75645 bytes mkdocs.yml | 1 + 7 files changed, 71 insertions(+) create mode 100644 docs/administration/authentication/okta.md create mode 100644 docs/media/authentication/netbox_okta_login.png create mode 100644 docs/media/authentication/okta_create_app_registration.png create mode 100644 docs/media/authentication/okta_integration_parameters.png create mode 100644 docs/media/authentication/okta_login_portal.png create mode 100644 docs/media/authentication/okta_web_app_integration.png diff --git a/docs/administration/authentication/okta.md b/docs/administration/authentication/okta.md new file mode 100644 index 000000000..ff552d730 --- /dev/null +++ b/docs/administration/authentication/okta.md @@ -0,0 +1,70 @@ +# Okta + +This guide explains how to configure single sign-on (SSO) support for NetBox using [Okta](https://www.okta.com/) as an authentication backend. + +## Okta Configuration + +!!! tip "Okta developer account" + Okta offers free developer accounts at . + +### 1. Create a test user (optional) + +Create a new user in the Okta admin portal to be used for testing. You can skip this step if you already have a suitable account created. + +### 2. Create an app registration + +Within the Okta administration dashboard, navigate to **Applications > Applications**, and click the "Create App Integration" button. Select "OIDC" as the sign-in method, and "Web application" for the application type. + +![Create an app registration](../../media/authentication/okta_create_app_registration.png) + +On the next page, give the app integration a name (e.g. "NetBox") and specify the sign-in and sign-out URIs. These URIs should follow the formats below: + +* Sign-in URI: `https://{netbox}/oauth/complete/okta-openidconnect/` +* Sign-out URI: `https://{netbox}/oauth/disconnect/okta-openidconnect/` + +![Web app integration](../../media/authentication/okta_web_app_integration.png) + +Under "Assignments," select the controlled access setting most appropriate for your organization. Click "Save" to complete the creation. + +Once finished, note the following parameters. These will be used to configured NetBox. + +* Client ID +* Client secret +* Okta domain + +![Okta integration parameters](../../media/authentication/okta_integration_parameters.png) + +## NetBox Configuration + +### 1. Enter configuration parameters + +Enter the following configuration parameters in `configuration.py`, substituting your own values: + +```python +REMOTE_AUTH_BACKEND = 'social_core.backends.okta_openidconnect.OktaOpenIdConnect' +SOCIAL_AUTH_OKTA_OPENIDCONNECT_KEY = '{Client ID}' +SOCIAL_AUTH_OKTA_OPENIDCONNECT_SECRET = '{Client secret}' +SOCIAL_AUTH_OKTA_OPENIDCONNECT_API_URL = 'https://{Okta domain}/oauth2/' +``` + +### 2. Restart NetBox + +Restart the NetBox services so that the new configuration takes effect. This is typically done with the command below: + +```no-highlight +sudo systemctl restart netbox +``` + +## Testing + +Log out of NetBox if already authenticated, and click the "Log In" button at top right. You should see the normal login form as well as an option to authenticate using Okta. Click that link. + +![NetBox Okta login form](../../media/authentication/netbox_okta_login.png) + +You should be redirected to Okta's authentication portal. Enter the username/email and password of your test account to continue. You may also be prompted to grant this application access to your account. + +![Okta login portal](../../media/authentication/okta_login_portal.png) + +If successful, you will be redirected back to the NetBox UI, and will be logged in as the Okta user. You can verify this by navigating to your profile (using the button at top right). + +This user account has been replicated locally to NetBox, and can now be assigned groups and permissions within the NetBox admin UI. diff --git a/docs/media/authentication/netbox_okta_login.png b/docs/media/authentication/netbox_okta_login.png new file mode 100644 index 0000000000000000000000000000000000000000..34df39cba17d2f8dfcc04f19d8f968d6037e7f56 GIT binary patch literal 16859 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 z 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

L+ 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 MT85|dPT55K57JvFy#N3J literal 0 HcmV?d00001 diff --git a/docs/media/authentication/okta_integration_parameters.png b/docs/media/authentication/okta_integration_parameters.png new file mode 100644 index 0000000000000000000000000000000000000000..b5d7794ec1296b1dbfead0c265e566d5bc7b35da GIT binary patch literal 39346 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 WGlwlr?b9g~ytFkhY80y74E`_INrwIa literal 0 HcmV?d00001 diff --git a/docs/media/authentication/okta_login_portal.png b/docs/media/authentication/okta_login_portal.png new file mode 100644 index 0000000000000000000000000000000000000000..48b62d3e08603e39eaa6f86e70333a77495e4b20 GIT binary patch literal 12277 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 KIs4M}2mb*>H(j;> literal 0 HcmV?d00001 diff --git a/docs/media/authentication/okta_web_app_integration.png b/docs/media/authentication/okta_web_app_integration.png new file mode 100644 index 0000000000000000000000000000000000000000..6587127c6eb3ca08be24f70cf0771a4d4701542d GIT binary patch literal 75645 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 literal 0 HcmV?d00001 diff --git a/mkdocs.yml b/mkdocs.yml index 7db4d24d7..f66700095 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -121,6 +121,7 @@ nav: - Authentication: - Overview: 'administration/authentication/overview.md' - Microsoft Azure AD: 'administration/authentication/microsoft-azure-ad.md' + - Okta: 'administration/authentication/okta.md' - Permissions: 'administration/permissions.md' - Housekeeping: 'administration/housekeeping.md' - Replicating NetBox: 'administration/replicating-netbox.md' From 1636508a6ac8df6b93d0ea5c621c174f605fd47a Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 18 Apr 2022 08:36:41 -0400 Subject: [PATCH 88/94] Fixes #9156: Fix loading UserConfig data from fixtures --- docs/release-notes/version-3.2.md | 1 + netbox/users/models.py | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index 97cedf0f5..339bc1061 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -5,6 +5,7 @@ ### Bug Fixes * [#9133](https://github.com/netbox-community/netbox/issues/9133) - Upgrade script should require Python 3.8 or later +* [#9156](https://github.com/netbox-community/netbox/issues/9156) - Fix loading UserConfig data from fixtures --- diff --git a/netbox/users/models.py b/netbox/users/models.py index 722ec5ba6..23068442e 100644 --- a/netbox/users/models.py +++ b/netbox/users/models.py @@ -173,11 +173,11 @@ class UserConfig(models.Model): @receiver(post_save, sender=User) -def create_userconfig(instance, created, **kwargs): +def create_userconfig(instance, created, raw=False, **kwargs): """ - Automatically create a new UserConfig when a new User is created. + Automatically create a new UserConfig when a new User is created. Skip this if importing a user from a fixture. """ - if created: + if created and not raw: config = get_config() UserConfig(user=instance, data=config.DEFAULT_USER_PREFERENCES).save() From 671e1aed9fba96e47377a003be362cce73c0082d Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 18 Apr 2022 08:43:46 -0400 Subject: [PATCH 89/94] Fixes #9151: Child prefix counts not annotated on aggregates list under RIR view --- docs/release-notes/version-3.2.md | 1 + netbox/ipam/views.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index 339bc1061..d573222ca 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -5,6 +5,7 @@ ### Bug Fixes * [#9133](https://github.com/netbox-community/netbox/issues/9133) - Upgrade script should require Python 3.8 or later +* [#9151](https://github.com/netbox-community/netbox/issues/9151) - Child prefix counts not annotated on aggregates list under RIR view * [#9156](https://github.com/netbox-community/netbox/issues/9156) - Fix loading UserConfig data from fixtures --- diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index 41bef2527..57a682c94 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -158,8 +158,8 @@ class RIRView(generic.ObjectView): queryset = RIR.objects.all() def get_extra_context(self, request, instance): - aggregates = Aggregate.objects.restrict(request.user, 'view').filter( - rir=instance + aggregates = Aggregate.objects.restrict(request.user, 'view').filter(rir=instance).annotate( + child_count=RawSQL('SELECT COUNT(*) FROM ipam_prefix WHERE ipam_prefix.prefix <<= ipam_aggregate.prefix', ()) ) aggregates_table = tables.AggregateTable(aggregates, exclude=('rir', 'utilization')) aggregates_table.configure(request) From 41244dc677a5989c4d3d692b8048495fe6a3c300 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 18 Apr 2022 08:56:28 -0400 Subject: [PATCH 90/94] Closes #9152: Annotate related object type under custom field view --- docs/release-notes/version-3.2.md | 4 ++++ netbox/templates/extras/customfield.html | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index d573222ca..ab3a5528f 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -2,6 +2,10 @@ ## v3.2.2 (FUTURE) +### Enhancements + +* [#9152](https://github.com/netbox-community/netbox/issues/9152) - Annotate related object type under custom field view + ### Bug Fixes * [#9133](https://github.com/netbox-community/netbox/issues/9133) - Upgrade script should require Python 3.8 or later diff --git a/netbox/templates/extras/customfield.html b/netbox/templates/extras/customfield.html index 9be7a485a..e8c3df460 100644 --- a/netbox/templates/extras/customfield.html +++ b/netbox/templates/extras/customfield.html @@ -21,7 +21,10 @@ Type - {{ object.get_type_display }} + + {{ object.get_type_display }} + {% if object.object_type %}({{ object.object_type.model|bettertitle }}){% endif %} + Description From 118bf5152c17eaa8fe044269af7de65536ec944b Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 18 Apr 2022 09:02:03 -0400 Subject: [PATCH 91/94] Fixes #9132: Limit location options by selected site when creating a wireless link --- docs/release-notes/version-3.2.md | 1 + netbox/wireless/forms/models.py | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index ab3a5528f..e1ad8e6bc 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -8,6 +8,7 @@ ### Bug Fixes +* [#9132](https://github.com/netbox-community/netbox/issues/9132) - Limit location options by selected site when creating a wireless link * [#9133](https://github.com/netbox-community/netbox/issues/9133) - Upgrade script should require Python 3.8 or later * [#9151](https://github.com/netbox-community/netbox/issues/9151) - Child prefix counts not annotated on aggregates list under RIR view * [#9156](https://github.com/netbox-community/netbox/issues/9156) - Fix loading UserConfig data from fixtures diff --git a/netbox/wireless/forms/models.py b/netbox/wireless/forms/models.py index 6d7dc84a9..d1012ba59 100644 --- a/netbox/wireless/forms/models.py +++ b/netbox/wireless/forms/models.py @@ -105,6 +105,9 @@ class WirelessLinkForm(NetBoxModelForm): ) location_a = DynamicModelChoiceField( queryset=Location.objects.all(), + query_params={ + 'site_id': '$site_a', + }, required=False, label='Location', initial_params={ @@ -142,6 +145,9 @@ class WirelessLinkForm(NetBoxModelForm): ) location_b = DynamicModelChoiceField( queryset=Location.objects.all(), + query_params={ + 'site_id': '$site_b', + }, required=False, label='Location', initial_params={ From d4f1cb5d6a3bfd505c1fc1e3d98c39d9b0fad283 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 18 Apr 2022 09:39:36 -0400 Subject: [PATCH 92/94] Fixes #9158: Do not list tags field for CSV forms which do not support tag assignment --- docs/release-notes/version-3.2.md | 1 + netbox/netbox/forms/base.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index e1ad8e6bc..6037a171f 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -12,6 +12,7 @@ * [#9133](https://github.com/netbox-community/netbox/issues/9133) - Upgrade script should require Python 3.8 or later * [#9151](https://github.com/netbox-community/netbox/issues/9151) - Child prefix counts not annotated on aggregates list under RIR view * [#9156](https://github.com/netbox-community/netbox/issues/9156) - Fix loading UserConfig data from fixtures +* [#9158](https://github.com/netbox-community/netbox/issues/9158) - Do not list tags field for CSV forms which do not support tag assignment --- diff --git a/netbox/netbox/forms/base.py b/netbox/netbox/forms/base.py index c842c6c06..0e232af1d 100644 --- a/netbox/netbox/forms/base.py +++ b/netbox/netbox/forms/base.py @@ -61,6 +61,8 @@ class NetBoxModelCSVForm(CSVModelForm, NetBoxModelForm): """ Base form for creating a NetBox objects from CSV data. Used for bulk importing. """ + tags = None # Temporary fix in lieu of tag import support (see #9158) + def _get_form_field(self, customfield): return customfield.to_form_field(for_csv_import=True) From a3805fe04dd310d633c5f0f5cbf808429bef7995 Mon Sep 17 00:00:00 2001 From: minitriga Date: Mon, 18 Apr 2022 18:07:41 +0100 Subject: [PATCH 93/94] Closes #9060: Implement modulebay, iventory items and device bay filters (#9146) * Closes #9060: Implement modulebay, iventory items and device bay filters * add blank line --- netbox/dcim/filtersets.py | 7 +++++++ netbox/dcim/forms/filtersets.py | 23 ++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py index 0f4e7cf7e..54f533a7f 100644 --- a/netbox/dcim/filtersets.py +++ b/netbox/dcim/filtersets.py @@ -435,6 +435,10 @@ class DeviceTypeFilterSet(NetBoxModelFilterSet): method='_device_bays', label='Has device bays', ) + inventory_items = django_filters.BooleanFilter( + method='_inventory_items', + label='Has inventory items', + ) class Meta: model = DeviceType @@ -479,6 +483,9 @@ class DeviceTypeFilterSet(NetBoxModelFilterSet): def _device_bays(self, queryset, name, value): return queryset.exclude(devicebaytemplates__isnull=value) + def _inventory_items(self, queryset, name, value): + return queryset.exclude(inventoryitemtemplates__isnull=value) + class ModuleTypeFilterSet(NetBoxModelFilterSet): manufacturer_id = django_filters.ModelMultipleChoiceFilter( diff --git a/netbox/dcim/forms/filtersets.py b/netbox/dcim/forms/filtersets.py index d5335947a..7f30941a2 100644 --- a/netbox/dcim/forms/filtersets.py +++ b/netbox/dcim/forms/filtersets.py @@ -331,7 +331,7 @@ class DeviceTypeFilterForm(NetBoxModelFilterSetForm): ('Hardware', ('manufacturer_id', 'part_number', 'subdevice_role', 'airflow')), ('Components', ( 'console_ports', 'console_server_ports', 'power_ports', 'power_outlets', 'interfaces', - 'pass_through_ports', + 'pass_through_ports', 'device_bays', 'module_bays', 'inventory_items', )), ) manufacturer_id = DynamicModelMultipleChoiceField( @@ -392,6 +392,27 @@ class DeviceTypeFilterForm(NetBoxModelFilterSetForm): choices=BOOLEAN_WITH_BLANK_CHOICES ) ) + device_bays = forms.NullBooleanField( + required=False, + label='Has device bays', + widget=StaticSelect( + choices=BOOLEAN_WITH_BLANK_CHOICES + ) + ) + module_bays = forms.NullBooleanField( + required=False, + label='Has module bays', + widget=StaticSelect( + choices=BOOLEAN_WITH_BLANK_CHOICES + ) + ) + inventory_items = forms.NullBooleanField( + required=False, + label='Has inventory items', + widget=StaticSelect( + choices=BOOLEAN_WITH_BLANK_CHOICES + ) + ) tag = TagFilterField(model) From bb99cee48abca3f1f3977deb2e7486503ef52501 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 18 Apr 2022 13:14:30 -0400 Subject: [PATCH 94/94] Changelog & test for #9060 --- docs/release-notes/version-3.2.md | 1 + netbox/dcim/tests/test_filtersets.py | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index 6037a171f..acbb68fad 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -4,6 +4,7 @@ ### Enhancements +* [#9060](https://github.com/netbox-community/netbox/issues/9060) - Add device type filters for device bays, module bays, and inventory items * [#9152](https://github.com/netbox-community/netbox/issues/9152) - Annotate related object type under custom field view ### Bug Fixes diff --git a/netbox/dcim/tests/test_filtersets.py b/netbox/dcim/tests/test_filtersets.py index 2e2c3baf7..8480c97bf 100644 --- a/netbox/dcim/tests/test_filtersets.py +++ b/netbox/dcim/tests/test_filtersets.py @@ -698,6 +698,9 @@ class DeviceTypeTestCase(TestCase, ChangeLoggedFilterSetTests): DeviceBayTemplate(device_type=device_types[0], name='Device Bay 1'), DeviceBayTemplate(device_type=device_types[1], name='Device Bay 2'), )) + # Assigned DeviceType must have parent subdevice_role + inventory_item = InventoryItemTemplate(device_type=device_types[1], name='Inventory Item 1') + inventory_item.save() def test_model(self): params = {'model': ['Model 1', 'Model 2']} @@ -784,6 +787,12 @@ class DeviceTypeTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'module_bays': 'false'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + def test_inventory_items(self): + params = {'inventory_items': 'true'} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + params = {'inventory_items': 'false'} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + class ModuleTypeTestCase(TestCase, ChangeLoggedFilterSetTests): queryset = ModuleType.objects.all()