From dc7411e4c5fe72c2dfa79e925fb014bcc7553189 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 11 Aug 2023 08:56:58 -0400 Subject: [PATCH 01/11] Fixes #13446: Don't disable bulk edit/delete buttons after deselecting "select all" checkbox --- docs/release-notes/version-3.5.md | 1 + netbox/project-static/dist/netbox.js | Bin 530613 -> 530368 bytes netbox/project-static/dist/netbox.js.map | Bin 450868 -> 450659 bytes .../project-static/src/buttons/selectAll.ts | 30 +----------------- 4 files changed, 2 insertions(+), 29 deletions(-) diff --git a/docs/release-notes/version-3.5.md b/docs/release-notes/version-3.5.md index cf47a3b23..fe0832c3b 100644 --- a/docs/release-notes/version-3.5.md +++ b/docs/release-notes/version-3.5.md @@ -18,6 +18,7 @@ * [#13343](https://github.com/netbox-community/netbox/issues/13343) - Fix filtering of circuits under provider network view * [#13369](https://github.com/netbox-community/netbox/issues/13369) - Fix job termination status for failed reports * [#13414](https://github.com/netbox-community/netbox/issues/13414) - Fix support for "hide-if-unset" custom fields on bulk import forms +* [#13446](https://github.com/netbox-community/netbox/issues/13446) - Don't disable bulk edit/delete buttons after deselecting "select all" checkbox --- diff --git a/netbox/project-static/dist/netbox.js b/netbox/project-static/dist/netbox.js index b62436d757a2b299e5bf0f33dcc4fbd67ec21e8c..84bfecae34920e732ecf52670208390ce6712040 100644 GIT binary patch delta 9766 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 R=VTT5U$4QMX#G;={{R{n`nLc8 delta 9842 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 diff --git a/netbox/project-static/dist/netbox.js.map b/netbox/project-static/dist/netbox.js.map index ed3833f982a5d0f0d81c6bcf7e90a86aeb99d789..7f2400ed2610973ed909703e534ec9b73c19c8ae 100644 GIT binary patch delta 44 zcmV+{0Mq}p!W-kj8-RoXgaU*Egaot&HT?rsH$s;W>ID^-;r#_p1Vd~^cDHc;1;pZx C4H8xW delta 254 zcmYL@%?bfw6o&INYb&MP!YM_R<$I1XO&XJiG)qlHgzVU`n0uI|o0zhdTnRh(Fy%XD zVRL#;y?^g}J$=+KaUm|orMR40?d%-wg+k!SG& r%d8<_AO4F%b#|B{*bT`;&4S3Z%JLU7(OR8kvdj+Y_D{EKW<6hDCyPpW diff --git a/netbox/project-static/src/buttons/selectAll.ts b/netbox/project-static/src/buttons/selectAll.ts index 64b98d390..f40520e26 100644 --- a/netbox/project-static/src/buttons/selectAll.ts +++ b/netbox/project-static/src/buttons/selectAll.ts @@ -1,4 +1,4 @@ -import { getElement, getElements, findFirstAdjacent } from '../util'; +import { getElements, findFirstAdjacent } from '../util'; /** * If any PK checkbox is checked, uncheck the select all table checkbox and the select all @@ -63,29 +63,6 @@ function handleSelectAllToggle(event: Event): void { } } -/** - * Synchronize the select all confirmation checkbox state with the select all confirmation button - * disabled state. If the select all confirmation checkbox is checked, the buttons should be - * enabled. If not, the buttons should be disabled. - * - * @param event Change Event - */ -function handleSelectAll(event: Event): void { - const target = event.currentTarget as HTMLInputElement; - const selectAllBox = getElement('select-all-box'); - if (selectAllBox !== null) { - for (const button of selectAllBox.querySelectorAll( - 'button[type="submit"]', - )) { - if (target.checked) { - button.disabled = false; - } else { - button.disabled = true; - } - } - } -} - /** * Initialize table select all elements. */ @@ -98,9 +75,4 @@ export function initSelectAll(): void { for (const element of getElements('input[type="checkbox"][name="pk"]')) { element.addEventListener('change', handlePkCheck); } - const selectAll = getElement('select-all'); - - if (selectAll !== null) { - selectAll.addEventListener('change', handleSelectAll); - } } From 9fd07b594c13266736cd67f1005334b916062828 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Date: Fri, 11 Aug 2023 20:49:03 +0700 Subject: [PATCH 02/11] 11578 mark swagger available- apis to accept lists in post (#13445) * 11578 change swagger for available-ips to accept lists * 11578 change swagger for available-xxx to accept lists --- netbox/ipam/api/views.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/netbox/ipam/api/views.py b/netbox/ipam/api/views.py index 99b4c023d..feffc3ff2 100644 --- a/netbox/ipam/api/views.py +++ b/netbox/ipam/api/views.py @@ -224,7 +224,10 @@ class AvailableASNsView(ObjectValidationMixin, APIView): return Response(serializer.data) - @extend_schema(methods=["post"], responses={201: serializers.ASNSerializer(many=True)}) + @extend_schema(methods=["post"], + responses={201: serializers.ASNSerializer(many=True)}, + request=serializers.ASNSerializer(many=True), + ) @advisory_lock(ADVISORY_LOCK_KEYS['available-asns']) def post(self, request, pk): self.queryset = self.queryset.restrict(request.user, 'add') @@ -293,7 +296,10 @@ class AvailablePrefixesView(ObjectValidationMixin, APIView): return Response(serializer.data) - @extend_schema(methods=["post"], responses={201: serializers.PrefixSerializer(many=True)}) + @extend_schema(methods=["post"], + responses={201: serializers.PrefixSerializer(many=True)}, + request=serializers.PrefixSerializer(many=True), + ) @advisory_lock(ADVISORY_LOCK_KEYS['available-prefixes']) def post(self, request, pk): self.queryset = self.queryset.restrict(request.user, 'add') @@ -388,7 +394,10 @@ class AvailableIPAddressesView(ObjectValidationMixin, APIView): return Response(serializer.data) - @extend_schema(methods=["post"], responses={201: serializers.IPAddressSerializer(many=True)}) + @extend_schema(methods=["post"], + responses={201: serializers.IPAddressSerializer(many=True)}, + request=serializers.IPAddressSerializer(many=True), + ) @advisory_lock(ADVISORY_LOCK_KEYS['available-ips']) def post(self, request, pk): self.queryset = self.queryset.restrict(request.user, 'add') @@ -468,7 +477,10 @@ class AvailableVLANsView(ObjectValidationMixin, APIView): return Response(serializer.data) - @extend_schema(methods=["post"], responses={201: serializers.VLANSerializer(many=True)}) + @extend_schema(methods=["post"], + responses={201: serializers.VLANSerializer(many=True)}, + request=serializers.VLANSerializer(many=True), + ) @advisory_lock(ADVISORY_LOCK_KEYS['available-vlans']) def post(self, request, pk): self.queryset = self.queryset.restrict(request.user, 'add') From 40afe6cf36be56c2aa3856a34254aea8c8934e14 Mon Sep 17 00:00:00 2001 From: "Daniel W. Anner" Date: Fri, 11 Aug 2023 11:00:26 -0400 Subject: [PATCH 03/11] Feature - Schema Generation (#13353) * Schema generation is working * Added option to either dump to a file or the console * Moving schema file and utilizing settings definition for file paths * Cleaning up the imports and fixing a few pythonic issues * Tweak command flags * Clean up choices mapping * Misc cleanup * Rename & move template file * Move management command from extras to dcim * Update release checklist --------- Co-authored-by: Jeremy Stretch --- contrib/generated_schema.json | 561 ++++++++++++++++++ docs/development/release-checklist.md | 10 + .../dcim/management/commands/buildschema.py | 62 ++ .../extras/schema/devicetype_schema.jinja2 | 93 +++ 4 files changed, 726 insertions(+) create mode 100644 contrib/generated_schema.json create mode 100644 netbox/dcim/management/commands/buildschema.py create mode 100644 netbox/templates/extras/schema/devicetype_schema.jinja2 diff --git a/contrib/generated_schema.json b/contrib/generated_schema.json new file mode 100644 index 000000000..8dbcb2847 --- /dev/null +++ b/contrib/generated_schema.json @@ -0,0 +1,561 @@ +{ + "type": "object", + "additionalProperties": false, + "definitions": { + "airflow": { + "type": "string", + "enum": [ + "front-to-rear", + "rear-to-front", + "left-to-right", + "right-to-left", + "side-to-rear", + "passive", + "mixed" + ] + }, + "weight-unit": { + "type": "string", + "enum": [ + "kg", + "g", + "lb", + "oz" + ] + }, + "subdevice-role": { + "type": "string", + "enum": [ + "parent", + "child" + ] + }, + "console-port": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "de-9", + "db-25", + "rj-11", + "rj-12", + "rj-45", + "mini-din-8", + "usb-a", + "usb-b", + "usb-c", + "usb-mini-a", + "usb-mini-b", + "usb-micro-a", + "usb-micro-b", + "usb-micro-ab", + "other" + ] + } + } + }, + "console-server-port": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "de-9", + "db-25", + "rj-11", + "rj-12", + "rj-45", + "mini-din-8", + "usb-a", + "usb-b", + "usb-c", + "usb-mini-a", + "usb-mini-b", + "usb-micro-a", + "usb-micro-b", + "usb-micro-ab", + "other" + ] + } + } + }, + "power-port": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "iec-60320-c6", + "iec-60320-c8", + "iec-60320-c14", + "iec-60320-c16", + "iec-60320-c20", + "iec-60320-c22", + "iec-60309-p-n-e-4h", + "iec-60309-p-n-e-6h", + "iec-60309-p-n-e-9h", + "iec-60309-2p-e-4h", + "iec-60309-2p-e-6h", + "iec-60309-2p-e-9h", + "iec-60309-3p-e-4h", + "iec-60309-3p-e-6h", + "iec-60309-3p-e-9h", + "iec-60309-3p-n-e-4h", + "iec-60309-3p-n-e-6h", + "iec-60309-3p-n-e-9h", + "iec-60906-1", + "nbr-14136-10a", + "nbr-14136-20a", + "nema-1-15p", + "nema-5-15p", + "nema-5-20p", + "nema-5-30p", + "nema-5-50p", + "nema-6-15p", + "nema-6-20p", + "nema-6-30p", + "nema-6-50p", + "nema-10-30p", + "nema-10-50p", + "nema-14-20p", + "nema-14-30p", + "nema-14-50p", + "nema-14-60p", + "nema-15-15p", + "nema-15-20p", + "nema-15-30p", + "nema-15-50p", + "nema-15-60p", + "nema-l1-15p", + "nema-l5-15p", + "nema-l5-20p", + "nema-l5-30p", + "nema-l5-50p", + "nema-l6-15p", + "nema-l6-20p", + "nema-l6-30p", + "nema-l6-50p", + "nema-l10-30p", + "nema-l14-20p", + "nema-l14-30p", + "nema-l14-50p", + "nema-l14-60p", + "nema-l15-20p", + "nema-l15-30p", + "nema-l15-50p", + "nema-l15-60p", + "nema-l21-20p", + "nema-l21-30p", + "nema-l22-30p", + "cs6361c", + "cs6365c", + "cs8165c", + "cs8265c", + "cs8365c", + "cs8465c", + "ita-c", + "ita-e", + "ita-f", + "ita-ef", + "ita-g", + "ita-h", + "ita-i", + "ita-j", + "ita-k", + "ita-l", + "ita-m", + "ita-n", + "ita-o", + "usb-a", + "usb-b", + "usb-c", + "usb-mini-a", + "usb-mini-b", + "usb-micro-a", + "usb-micro-b", + "usb-micro-ab", + "usb-3-b", + "usb-3-micro-b", + "dc-terminal", + "saf-d-grid", + "neutrik-powercon-20", + "neutrik-powercon-32", + "neutrik-powercon-true1", + "neutrik-powercon-true1-top", + "ubiquiti-smartpower", + "hardwired", + "other" + ] + } + } + }, + "power-outlet": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "iec-60320-c5", + "iec-60320-c7", + "iec-60320-c13", + "iec-60320-c15", + "iec-60320-c19", + "iec-60320-c21", + "iec-60309-p-n-e-4h", + "iec-60309-p-n-e-6h", + "iec-60309-p-n-e-9h", + "iec-60309-2p-e-4h", + "iec-60309-2p-e-6h", + "iec-60309-2p-e-9h", + "iec-60309-3p-e-4h", + "iec-60309-3p-e-6h", + "iec-60309-3p-e-9h", + "iec-60309-3p-n-e-4h", + "iec-60309-3p-n-e-6h", + "iec-60309-3p-n-e-9h", + "iec-60906-1", + "nbr-14136-10a", + "nbr-14136-20a", + "nema-1-15r", + "nema-5-15r", + "nema-5-20r", + "nema-5-30r", + "nema-5-50r", + "nema-6-15r", + "nema-6-20r", + "nema-6-30r", + "nema-6-50r", + "nema-10-30r", + "nema-10-50r", + "nema-14-20r", + "nema-14-30r", + "nema-14-50r", + "nema-14-60r", + "nema-15-15r", + "nema-15-20r", + "nema-15-30r", + "nema-15-50r", + "nema-15-60r", + "nema-l1-15r", + "nema-l5-15r", + "nema-l5-20r", + "nema-l5-30r", + "nema-l5-50r", + "nema-l6-15r", + "nema-l6-20r", + "nema-l6-30r", + "nema-l6-50r", + "nema-l10-30r", + "nema-l14-20r", + "nema-l14-30r", + "nema-l14-50r", + "nema-l14-60r", + "nema-l15-20r", + "nema-l15-30r", + "nema-l15-50r", + "nema-l15-60r", + "nema-l21-20r", + "nema-l21-30r", + "nema-l22-30r", + "CS6360C", + "CS6364C", + "CS8164C", + "CS8264C", + "CS8364C", + "CS8464C", + "ita-e", + "ita-f", + "ita-g", + "ita-h", + "ita-i", + "ita-j", + "ita-k", + "ita-l", + "ita-m", + "ita-n", + "ita-o", + "ita-multistandard", + "usb-a", + "usb-micro-b", + "usb-c", + "dc-terminal", + "hdot-cx", + "saf-d-grid", + "neutrik-powercon-20a", + "neutrik-powercon-32a", + "neutrik-powercon-true1", + "neutrik-powercon-true1-top", + "ubiquiti-smartpower", + "hardwired", + "other" + ] + }, + "feed-leg": { + "type": "string", + "enum": [ + "A", + "B", + "C" + ] + } + } + }, + "interface": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "virtual", + "bridge", + "lag", + "100base-fx", + "100base-lfx", + "100base-tx", + "100base-t1", + "1000base-t", + "2.5gbase-t", + "5gbase-t", + "10gbase-t", + "10gbase-cx4", + "1000base-x-gbic", + "1000base-x-sfp", + "10gbase-x-sfpp", + "10gbase-x-xfp", + "10gbase-x-xenpak", + "10gbase-x-x2", + "25gbase-x-sfp28", + "50gbase-x-sfp56", + "40gbase-x-qsfpp", + "50gbase-x-sfp28", + "100gbase-x-cfp", + "100gbase-x-cfp2", + "200gbase-x-cfp2", + "100gbase-x-cfp4", + "100gbase-x-cxp", + "100gbase-x-cpak", + "100gbase-x-dsfp", + "100gbase-x-sfpdd", + "100gbase-x-qsfp28", + "100gbase-x-qsfpdd", + "200gbase-x-qsfp56", + "200gbase-x-qsfpdd", + "400gbase-x-qsfpdd", + "400gbase-x-osfp", + "400gbase-x-cdfp", + "400gbase-x-cfp8", + "800gbase-x-qsfpdd", + "800gbase-x-osfp", + "1000base-kx", + "10gbase-kr", + "10gbase-kx4", + "25gbase-kr", + "40gbase-kr4", + "50gbase-kr", + "100gbase-kp4", + "100gbase-kr2", + "100gbase-kr4", + "ieee802.11a", + "ieee802.11g", + "ieee802.11n", + "ieee802.11ac", + "ieee802.11ad", + "ieee802.11ax", + "ieee802.11ay", + "ieee802.15.1", + "other-wireless", + "gsm", + "cdma", + "lte", + "sonet-oc3", + "sonet-oc12", + "sonet-oc48", + "sonet-oc192", + "sonet-oc768", + "sonet-oc1920", + "sonet-oc3840", + "1gfc-sfp", + "2gfc-sfp", + "4gfc-sfp", + "8gfc-sfpp", + "16gfc-sfpp", + "32gfc-sfp28", + "64gfc-qsfpp", + "128gfc-qsfp28", + "infiniband-sdr", + "infiniband-ddr", + "infiniband-qdr", + "infiniband-fdr10", + "infiniband-fdr", + "infiniband-edr", + "infiniband-hdr", + "infiniband-ndr", + "infiniband-xdr", + "t1", + "e1", + "t3", + "e3", + "xdsl", + "docsis", + "gpon", + "xg-pon", + "xgs-pon", + "ng-pon2", + "epon", + "10g-epon", + "cisco-stackwise", + "cisco-stackwise-plus", + "cisco-flexstack", + "cisco-flexstack-plus", + "cisco-stackwise-80", + "cisco-stackwise-160", + "cisco-stackwise-320", + "cisco-stackwise-480", + "cisco-stackwise-1t", + "juniper-vcp", + "extreme-summitstack", + "extreme-summitstack-128", + "extreme-summitstack-256", + "extreme-summitstack-512", + "other" + ] + }, + "poe_mode": { + "type": "string", + "enum": [ + "pd", + "pse" + ] + }, + "poe_type": { + "type": "string", + "enum": [ + "type1-ieee802.3af", + "type2-ieee802.3at", + "type3-ieee802.3bt", + "type4-ieee802.3bt", + "passive-24v-2pair", + "passive-24v-4pair", + "passive-48v-2pair", + "passive-48v-4pair" + ] + } + } + }, + "front-port": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "8p8c", + "8p6c", + "8p4c", + "8p2c", + "6p6c", + "6p4c", + "6p2c", + "4p4c", + "4p2c", + "gg45", + "tera-4p", + "tera-2p", + "tera-1p", + "110-punch", + "bnc", + "f", + "n", + "mrj21", + "fc", + "lc", + "lc-pc", + "lc-upc", + "lc-apc", + "lsh", + "lsh-pc", + "lsh-upc", + "lsh-apc", + "lx5", + "lx5-pc", + "lx5-upc", + "lx5-apc", + "mpo", + "mtrj", + "sc", + "sc-pc", + "sc-upc", + "sc-apc", + "st", + "cs", + "sn", + "sma-905", + "sma-906", + "urm-p2", + "urm-p4", + "urm-p8", + "splice", + "other" + ] + } + } + }, + "rear-port": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "8p8c", + "8p6c", + "8p4c", + "8p2c", + "6p6c", + "6p4c", + "6p2c", + "4p4c", + "4p2c", + "gg45", + "tera-4p", + "tera-2p", + "tera-1p", + "110-punch", + "bnc", + "f", + "n", + "mrj21", + "fc", + "lc", + "lc-pc", + "lc-upc", + "lc-apc", + "lsh", + "lsh-pc", + "lsh-upc", + "lsh-apc", + "lx5", + "lx5-pc", + "lx5-upc", + "lx5-apc", + "mpo", + "mtrj", + "sc", + "sc-pc", + "sc-upc", + "sc-apc", + "st", + "cs", + "sn", + "sma-905", + "sma-906", + "urm-p2", + "urm-p4", + "urm-p8", + "splice", + "other" + ] + } + } + } + } +} diff --git a/docs/development/release-checklist.md b/docs/development/release-checklist.md index 000948ee7..68b777111 100644 --- a/docs/development/release-checklist.md +++ b/docs/development/release-checklist.md @@ -70,6 +70,16 @@ Before each release, update each of NetBox's Python dependencies to its most rec In cases where upgrading a dependency to its most recent release is breaking, it should be constrained to its current minor version in `base_requirements.txt` with an explanatory comment and revisited for the next major NetBox release (see the [Address Constrained Dependencies](#address-constrained-dependencies) section above). +### Rebuild the Device Type Definition Schema + +Run the following command to update the device type definition validation schema: + +```nohighlight +./manage.py buildschema --write +``` + +This will automatically update the schema file at `contrib/generated_schema.json`. + ### Update Version and Changelog * Update the `VERSION` constant in `settings.py` to the new release version. diff --git a/netbox/dcim/management/commands/buildschema.py b/netbox/dcim/management/commands/buildschema.py new file mode 100644 index 000000000..44a0e95f2 --- /dev/null +++ b/netbox/dcim/management/commands/buildschema.py @@ -0,0 +1,62 @@ +import json +import os + +from django.conf import settings +from django.core.management.base import BaseCommand +from jinja2 import FileSystemLoader, Environment + +from dcim.choices import * + +TEMPLATE_FILENAME = 'devicetype_schema.jinja2' +OUTPUT_FILENAME = 'contrib/generated_schema.json' + +CHOICES_MAP = { + 'airflow_choices': DeviceAirflowChoices, + 'weight_unit_choices': WeightUnitChoices, + 'subdevice_role_choices': SubdeviceRoleChoices, + 'console_port_type_choices': ConsolePortTypeChoices, + 'console_server_port_type_choices': ConsolePortTypeChoices, + 'power_port_type_choices': PowerPortTypeChoices, + 'power_outlet_type_choices': PowerOutletTypeChoices, + 'power_outlet_feedleg_choices': PowerOutletFeedLegChoices, + 'interface_type_choices': InterfaceTypeChoices, + 'interface_poe_mode_choices': InterfacePoEModeChoices, + 'interface_poe_type_choices': InterfacePoETypeChoices, + 'front_port_type_choices': PortTypeChoices, + 'rear_port_type_choices': PortTypeChoices, +} + + +class Command(BaseCommand): + help = "Generate JSON schema for validating NetBox device type definitions" + + def add_arguments(self, parser): + parser.add_argument( + '--write', + action='store_true', + help="Write the generated schema to file" + ) + + def handle(self, *args, **kwargs): + # Initialize template + template_loader = FileSystemLoader(searchpath=f'{settings.TEMPLATES_DIR}/extras/schema/') + template_env = Environment(loader=template_loader) + template = template_env.get_template(TEMPLATE_FILENAME) + + # Render template + context = { + key: json.dumps(choices.values()) + for key, choices in CHOICES_MAP.items() + } + rendered = template.render(**context) + + if kwargs['write']: + # $root/contrib/generated_schema.json + filename = os.path.join(os.path.split(settings.BASE_DIR)[0], OUTPUT_FILENAME) + with open(filename, mode='w', encoding='UTF-8') as f: + f.write(json.dumps(json.loads(rendered), indent=4)) + f.write('\n') + f.close() + self.stdout.write(self.style.SUCCESS(f"Schema written to {filename}.")) + else: + self.stdout.write(rendered) diff --git a/netbox/templates/extras/schema/devicetype_schema.jinja2 b/netbox/templates/extras/schema/devicetype_schema.jinja2 new file mode 100644 index 000000000..b08ab24de --- /dev/null +++ b/netbox/templates/extras/schema/devicetype_schema.jinja2 @@ -0,0 +1,93 @@ +{ + "type": "object", + "additionalProperties": false, + "definitions": { + "airflow": { + "type": "string", + "enum": {{ airflow_choices }} + }, + "weight-unit": { + "type": "string", + "enum": {{ weight_unit_choices }} + }, + "subdevice-role": { + "type": "string", + "enum": {{ subdevice_role_choices }} + }, + "console-port": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": {{ console_port_type_choices }} + } + } + }, + "console-server-port": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": {{ console_server_port_type_choices }} + } + } + }, + "power-port": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": {{ power_port_type_choices }} + } + } + }, + "power-outlet": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": {{ power_outlet_type_choices }} + }, + "feed-leg": { + "type": "string", + "enum": {{ power_outlet_feedleg_choices }} + } + } + }, + "interface": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": {{ interface_type_choices }} + }, + "poe_mode": { + "type": "string", + "enum": {{ interface_poe_mode_choices }} + }, + "poe_type": { + "type": "string", + "enum": {{ interface_poe_type_choices }} + } + } + }, + "front-port": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": {{ front_port_type_choices }} + } + } + }, + "rear-port": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": {{ rear_port_type_choices}} + } + } + } + } +} From 5de9d3f15f4f5bc82ebbe5f650dcd528fe9bf250 Mon Sep 17 00:00:00 2001 From: kkthxbye <400797+kkthxbye-code@users.noreply.github.com> Date: Fri, 11 Aug 2023 17:53:16 +0200 Subject: [PATCH 04/11] Fixes #12639 - Make sure name expansions throws a validation error on decrementing ranges (#13326) * Fixes #12639 - Make sure name expansions throws a validation error on decrementing ranges * Fix pep8 * Also fail on equal start & end values --------- Co-authored-by: Jeremy Stretch --- netbox/dcim/forms/object_create.py | 5 ++++- netbox/utilities/forms/utils.py | 7 +++++++ netbox/utilities/tests/test_forms.py | 5 +++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/netbox/dcim/forms/object_create.py b/netbox/dcim/forms/object_create.py index 9589ab533..f37edee0a 100644 --- a/netbox/dcim/forms/object_create.py +++ b/netbox/dcim/forms/object_create.py @@ -52,7 +52,10 @@ class ComponentCreateForm(forms.Form): super().clean() # Validate that all replication fields generate an equal number of values - pattern_count = len(self.cleaned_data[self.replication_fields[0]]) + if not (patterns := self.cleaned_data.get(self.replication_fields[0])): + return + + pattern_count = len(patterns) for field_name in self.replication_fields: value_count = len(self.cleaned_data[field_name]) if self.cleaned_data[field_name] and value_count != pattern_count: diff --git a/netbox/utilities/forms/utils.py b/netbox/utilities/forms/utils.py index 5100b1714..4d737f163 100644 --- a/netbox/utilities/forms/utils.py +++ b/netbox/utilities/forms/utils.py @@ -60,6 +60,9 @@ def parse_alphanumeric_range(string): except ValueError: begin, end = dash_range, dash_range if begin.isdigit() and end.isdigit(): + if int(begin) >= int(end): + raise forms.ValidationError(f'Range "{dash_range}" is invalid.') + for n in list(range(int(begin), int(end) + 1)): values.append(n) else: @@ -71,6 +74,10 @@ def parse_alphanumeric_range(string): # Not a valid range (more than a single character) if not len(begin) == len(end) == 1: raise forms.ValidationError(f'Range "{dash_range}" is invalid.') + + if ord(begin) >= ord(end): + raise forms.ValidationError(f'Range "{dash_range}" is invalid.') + for n in list(range(ord(begin), ord(end) + 1)): values.append(chr(n)) return values diff --git a/netbox/utilities/tests/test_forms.py b/netbox/utilities/tests/test_forms.py index b8cff2996..79ba3f4d8 100644 --- a/netbox/utilities/tests/test_forms.py +++ b/netbox/utilities/tests/test_forms.py @@ -264,8 +264,9 @@ class ExpandAlphanumeric(TestCase): self.assertEqual(sorted(expand_alphanumeric_pattern('r[a-9]a')), []) def test_invalid_range_bounds(self): - self.assertEqual(sorted(expand_alphanumeric_pattern('r[9-8]a')), []) - self.assertEqual(sorted(expand_alphanumeric_pattern('r[b-a]a')), []) + with self.assertRaises(forms.ValidationError): + sorted(expand_alphanumeric_pattern('r[9-8]a')) + sorted(expand_alphanumeric_pattern('r[b-a]a')) def test_invalid_range_len(self): with self.assertRaises(forms.ValidationError): From be3f48c6778414a9f129d2bcef8bfbe259d781c1 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Mon, 14 Aug 2023 13:29:11 +0530 Subject: [PATCH 05/11] Fixed spelling for Attributes #13460 --- netbox/ipam/forms/filtersets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/ipam/forms/filtersets.py b/netbox/ipam/forms/filtersets.py index 53fecfe2f..f00082863 100644 --- a/netbox/ipam/forms/filtersets.py +++ b/netbox/ipam/forms/filtersets.py @@ -253,7 +253,7 @@ class IPRangeFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm): model = IPRange fieldsets = ( (None, ('q', 'filter_id', 'tag')), - ('Attriubtes', ('family', 'vrf_id', 'status', 'role_id', 'mark_utilized')), + ('Attributes', ('family', 'vrf_id', 'status', 'role_id', 'mark_utilized')), ('Tenant', ('tenant_group_id', 'tenant_id')), ) family = forms.ChoiceField( From b5837707652da3c18739b10efbf49a5fbc2d7762 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 14 Aug 2023 08:51:16 -0400 Subject: [PATCH 06/11] Fixes #13451: Disable table ordering for custom link columns --- docs/release-notes/version-3.5.md | 1 + netbox/netbox/tables/columns.py | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/release-notes/version-3.5.md b/docs/release-notes/version-3.5.md index fe0832c3b..30ffef393 100644 --- a/docs/release-notes/version-3.5.md +++ b/docs/release-notes/version-3.5.md @@ -19,6 +19,7 @@ * [#13369](https://github.com/netbox-community/netbox/issues/13369) - Fix job termination status for failed reports * [#13414](https://github.com/netbox-community/netbox/issues/13414) - Fix support for "hide-if-unset" custom fields on bulk import forms * [#13446](https://github.com/netbox-community/netbox/issues/13446) - Don't disable bulk edit/delete buttons after deselecting "select all" checkbox +* [#13451](https://github.com/netbox-community/netbox/issues/13451) - Disable table ordering for custom link columns --- diff --git a/netbox/netbox/tables/columns.py b/netbox/netbox/tables/columns.py index 9ef327026..399b3c184 100644 --- a/netbox/netbox/tables/columns.py +++ b/netbox/netbox/tables/columns.py @@ -504,9 +504,9 @@ class CustomLinkColumn(tables.Column): """ def __init__(self, customlink, *args, **kwargs): self.customlink = customlink - kwargs['accessor'] = Accessor('pk') - if 'verbose_name' not in kwargs: - kwargs['verbose_name'] = customlink.name + kwargs.setdefault('accessor', Accessor('pk')) + kwargs.setdefault('orderable', False) + kwargs.setdefault('verbose_name', customlink.name) super().__init__(*args, **kwargs) From b9b9c065cc3723bb390b65e8ac1519beb8104e9e Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 14 Aug 2023 08:55:47 -0400 Subject: [PATCH 07/11] Changelog for #10030, #11578, #12639 --- docs/release-notes/version-3.5.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/release-notes/version-3.5.md b/docs/release-notes/version-3.5.md index 30ffef393..cc8f61802 100644 --- a/docs/release-notes/version-3.5.md +++ b/docs/release-notes/version-3.5.md @@ -4,6 +4,7 @@ ### Enhancements +* [#10030](https://github.com/netbox-community/netbox/issues/10030) - Ship a validation schema for the device type library with each release * [#11675](https://github.com/netbox-community/netbox/issues/11675) - Add support for specifying import/export route targets during VRF bulk import * [#11922](https://github.com/netbox-community/netbox/issues/11922) - Automatically populate any VDC assignments from the parent when adding a child interface via the UI * [#12889](https://github.com/netbox-community/netbox/issues/12889) - Add 400GE CFP2 interface type @@ -13,6 +14,8 @@ ### Bug Fixes +* [#11578](https://github.com/netbox-community/netbox/issues/11578) - Fix schema definition for available IP & VLAN REST API endpoints +* [#12639](https://github.com/netbox-community/netbox/issues/12639) - Raise validation error for invalid alphanumeric ranges when creating objects * [#12665](https://github.com/netbox-community/netbox/issues/12665) - Avoid escaping semicolons when rendering custom links * [#12750](https://github.com/netbox-community/netbox/issues/12750) - Automatically delete an AutoSyncRecord when its object is deleted * [#13343](https://github.com/netbox-community/netbox/issues/13343) - Fix filtering of circuits under provider network view From ea107b6b86015f3fd97995bb7ea738a0d95a83c1 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Mon, 14 Aug 2023 18:57:26 +0530 Subject: [PATCH 08/11] adds object view to allow changelog page to be opened #13463 --- netbox/templates/extras/imageattachment.html | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 netbox/templates/extras/imageattachment.html diff --git a/netbox/templates/extras/imageattachment.html b/netbox/templates/extras/imageattachment.html new file mode 100644 index 000000000..1968344cc --- /dev/null +++ b/netbox/templates/extras/imageattachment.html @@ -0,0 +1,4 @@ +{% extends 'generic/object.html' %} + +{% block tabs %} +{% endblock %} From 892c10b1f077b5d5147dd408a5d06ee3e7c3d0f8 Mon Sep 17 00:00:00 2001 From: "Joel D. Tague" Date: Fri, 11 Aug 2023 13:36:34 -0400 Subject: [PATCH 09/11] feat: add 200Gbps & 400Gbps interface speed options --- netbox/dcim/choices.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/netbox/dcim/choices.py b/netbox/dcim/choices.py index 21bd3ed7e..ba722508a 100644 --- a/netbox/dcim/choices.py +++ b/netbox/dcim/choices.py @@ -1141,6 +1141,8 @@ class InterfaceSpeedChoices(ChoiceSet): (25000000, '25 Gbps'), (40000000, '40 Gbps'), (100000000, '100 Gbps'), + (200000000, '200 Gbps'), + (400000000, '400 Gbps'), ] From e61795d5c66c8c9121177a1ece0df71835ebe723 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 15 Aug 2023 09:18:15 -0400 Subject: [PATCH 10/11] Release v3.5.8 --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- .github/ISSUE_TEMPLATE/feature_request.yaml | 2 +- docs/release-notes/version-3.5.md | 3 ++- netbox/netbox/settings.py | 2 +- requirements.txt | 10 +++++----- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 42a716ae7..b43968731 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.5.7 + placeholder: v3.5.8 validations: required: true - type: dropdown diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index b04fda1b6..5df3069ba 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.5.7 + placeholder: v3.5.8 validations: required: true - type: dropdown diff --git a/docs/release-notes/version-3.5.md b/docs/release-notes/version-3.5.md index cc8f61802..6d9ae5509 100644 --- a/docs/release-notes/version-3.5.md +++ b/docs/release-notes/version-3.5.md @@ -1,6 +1,6 @@ # NetBox v3.5 -## v3.5.8 (FUTURE) +## v3.5.8 (2023-08-15) ### Enhancements @@ -11,6 +11,7 @@ * [#13033](https://github.com/netbox-community/netbox/issues/13033) - Add human-friendly speed column to interfaces table * [#13151](https://github.com/netbox-community/netbox/issues/13151) - Add "assigned" filter for IP addresses * [#13368](https://github.com/netbox-community/netbox/issues/13368) - List installed plugins on the server error report page +* [#13442](https://github.com/netbox-community/netbox/issues/13442) - Add 200 and 400 Gbps speeds to dropdown choices on interface form ### Bug Fixes diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 2744ba701..acad437fc 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -25,7 +25,7 @@ from netbox.constants import RQ_QUEUE_DEFAULT, RQ_QUEUE_HIGH, RQ_QUEUE_LOW # Environment setup # -VERSION = '3.5.8-dev' +VERSION = '3.5.8' # Hostname HOSTNAME = platform.node() diff --git a/requirements.txt b/requirements.txt index f1235fa2c..2ea0f2522 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ bleach==6.0.0 -boto3==1.28.14 +boto3==1.28.26 Django==4.1.10 django-cors-headers==4.2.0 -django-debug-toolbar==4.1.0 +django-debug-toolbar==4.2.0 django-filter==23.2 django-graphiql-debug-toolbar==0.2.0 django-mptt==0.14 @@ -16,7 +16,7 @@ django-taggit==4.0.0 django-timezone-field==5.1 djangorestframework==3.14.0 drf-spectacular==0.26.4 -drf-spectacular-sidecar==2023.7.1 +drf-spectacular-sidecar==2023.8.1 dulwich==0.21.5 feedparser==6.0.10 graphene-django==3.0.0 @@ -27,9 +27,9 @@ mkdocs-material==9.1.21 mkdocstrings[python-legacy]==0.22.0 netaddr==0.8.0 Pillow==10.0.0 -psycopg2-binary==2.9.6 +psycopg2-binary==2.9.7 PyYAML==6.0.1 -sentry-sdk==1.28.1 +sentry-sdk==1.29.2 social-auth-app-django==5.2.0 social-auth-core[openidconnect]==4.4.2 svgwrite==1.4.3 From 1c9a8ec6bd0a4b803652a721cf81e91a0bdd5340 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 15 Aug 2023 10:00:24 -0400 Subject: [PATCH 11/11] PRVB --- docs/release-notes/version-3.5.md | 4 ++++ netbox/netbox/settings.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.5.md b/docs/release-notes/version-3.5.md index 6d9ae5509..f7778275b 100644 --- a/docs/release-notes/version-3.5.md +++ b/docs/release-notes/version-3.5.md @@ -1,5 +1,9 @@ # NetBox v3.5 +## v3.5.9 (FUTURE) + +--- + ## v3.5.8 (2023-08-15) ### Enhancements diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index acad437fc..aace6745a 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -25,7 +25,7 @@ from netbox.constants import RQ_QUEUE_DEFAULT, RQ_QUEUE_HIGH, RQ_QUEUE_LOW # Environment setup # -VERSION = '3.5.8' +VERSION = '3.5.9-dev' # Hostname HOSTNAME = platform.node()