Compare commits

..

12 Commits

Author SHA1 Message Date
Jeremy Stretch
0b120e6ad2 Merge pull request #17346 from netbox-community/develop
Release v4.0.11
2024-09-03 10:50:46 -04:00
Jeremy Stretch
e174a8af09 Release v4.0.11 2024-09-03 10:33:47 -04:00
Jeremy Stretch
77d1dc4807 Compile translations 2024-09-03 10:16:26 -04:00
dependabot[bot]
2f1798c7de Bump micromatch from 4.0.5 to 4.0.8 in /netbox/project-static
Bumps [micromatch](https://github.com/micromatch/micromatch) from 4.0.5 to 4.0.8.
- [Release notes](https://github.com/micromatch/micromatch/releases)
- [Changelog](https://github.com/micromatch/micromatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/micromatch/compare/4.0.5...4.0.8)

---
updated-dependencies:
- dependency-name: micromatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-03 10:12:50 -04:00
transifex-integration[bot]
52b7f62b10 Updates for project NetBox (#17345)
* Translate django.po in es

100% translated source file: 'django.po'
on 'es'.

* Translate django.po in ru

100% translated source file: 'django.po'
on 'ru'.

* Translate django.po in ja

100% translated source file: 'django.po'
on 'ja'.

* Translate django.po in cs

100% translated source file: 'django.po'
on 'cs'.

* Translate django.po in da

100% translated source file: 'django.po'
on 'da'.

* Translate django.po in nl

100% translated source file: 'django.po'
on 'nl'.

* Translate django.po in de

100% translated source file: 'django.po'
on 'de'.

* Translate django.po in pl

100% translated source file: 'django.po'
on 'pl'.

* Translate django.po in it

100% translated source file: 'django.po'
on 'it'.

* Translate django.po in tr

100% translated source file: 'django.po'
on 'tr'.

* Translate django.po in uk

100% translated source file: 'django.po'
on 'uk'.

* Translate django.po in pt

100% translated source file: 'django.po'
on 'pt'.

* Translate django.po in fr

100% translated source file: 'django.po'
on 'fr'.

* Translate django.po in zh

100% translated source file: 'django.po'
on 'zh'.

---------

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-09-03 10:11:56 -04:00
Brian Candler
7a2ff96abe Hide exception in ObjectCountsWidget for models without a xxx_list view function (#17342)
* Hide exception in ObjectCountsWidget for models without a `xxx_list` view function

Fixes #17341

* Disable hyperlink for invalid view names

---------

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
2024-09-03 09:38:06 -04:00
Jeremy Stretch
814b699204 Fixes #17323: Associate job with script object when executed using runscript command 2024-09-03 09:20:18 -04:00
Jeremy Stretch
d18a853baa Fixes #17337: Fix ordering of virtual device contexts by device name 2024-09-03 08:58:13 -04:00
Arzhel Younsi
b2bbdbf1d9 runscript: use the previously defined "user"
There is already a logic set earlier in the code to define "user" if --user is passed as parameter, and default to the user with the lowest ID no none is provided.
This patch uses this "user" to run the job instead of always applying the default.
2024-09-03 08:42:37 -04:00
Daniel Sheppard
4fead1c85f Fixes: #17310 - Properly restrict GraphQL related object queries (#17312)
* Fixes: #17310 - Fix GraphQL restriction of related objects

* Fix some failing tests

* Fix test
2024-08-30 14:22:58 -04:00
github-actions
91ad3f22a3 Update source translation strings 2024-08-30 05:02:15 +00:00
Jeremy Stretch
31f167d0f9 PRVB 2024-08-29 09:51:06 -04:00
49 changed files with 4454 additions and 4338 deletions

View File

@@ -26,7 +26,7 @@ body:
attributes:
label: NetBox Version
description: What version of NetBox are you currently running?
placeholder: v4.0.10
placeholder: v4.0.11
validations:
required: true
- type: dropdown

View File

@@ -14,7 +14,7 @@ body:
attributes:
label: NetBox version
description: What version of NetBox are you currently running?
placeholder: v4.0.10
placeholder: v4.0.11
validations:
required: true
- type: dropdown

View File

@@ -1,5 +1,15 @@
# NetBox v4.0
## v4.0.11 (2024-09-03)
### Bug Fixes
* [#17310](https://github.com/netbox-community/netbox/issues/17310) - Enforce restricted queryset for related objects in GraphQL API requests
* [#17321](https://github.com/netbox-community/netbox/issues/17321) - Ensure the job is attributed to the specified user when using the `runscript` management command
* [#17323](https://github.com/netbox-community/netbox/issues/17323) - Associate job with script object when executed using the `runscript` management command
* [#17337](https://github.com/netbox-community/netbox/issues/17337) - Fix ordering of virtual device contexts by device name
* [#17341](https://github.com/netbox-community/netbox/issues/17341) - Avoid `NoReverseMatch` exceptions with specific dashboard widget configurations
## v4.0.10 (2024-08-29)
### Enhancements

View File

@@ -96,6 +96,7 @@ class CircuitTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'status': 'planned',
}
user_permissions = ('circuits.view_provider', 'circuits.view_circuittype')
@classmethod
def setUpTestData(cls):
@@ -150,6 +151,7 @@ class CircuitTest(APIViewTestCases.APIViewTestCase):
class CircuitTerminationTest(APIViewTestCases.APIViewTestCase):
model = CircuitTermination
brief_fields = ['_occupied', 'cable', 'circuit', 'description', 'display', 'id', 'term_side', 'url']
user_permissions = ('circuits.view_circuit', )
@classmethod
def setUpTestData(cls):
@@ -209,6 +211,7 @@ class CircuitTerminationTest(APIViewTestCases.APIViewTestCase):
class ProviderAccountTest(APIViewTestCases.APIViewTestCase):
model = ProviderAccount
brief_fields = ['account', 'description', 'display', 'id', 'name', 'url']
user_permissions = ('circuits.view_provider', )
@classmethod
def setUpTestData(cls):
@@ -252,6 +255,7 @@ class ProviderAccountTest(APIViewTestCases.APIViewTestCase):
class ProviderNetworkTest(APIViewTestCases.APIViewTestCase):
model = ProviderNetwork
brief_fields = ['description', 'display', 'id', 'name', 'url']
user_permissions = ('circuits.view_provider', )
@classmethod
def setUpTestData(cls):

View File

@@ -57,6 +57,7 @@ class DataFileTest(
):
model = DataFile
brief_fields = ['display', 'id', 'path', 'url']
user_permissions = ('core.view_datasource', )
@classmethod
def setUpTestData(cls):

View File

@@ -1031,7 +1031,7 @@ class VirtualDeviceContextTable(TenancyColumnsMixin, NetBoxTable):
)
device = tables.TemplateColumn(
verbose_name=_('Device'),
order_by=('_name',),
order_by=('device___name',),
template_code=DEVICE_LINK,
linkify=True
)

View File

@@ -195,6 +195,7 @@ class LocationTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'description': 'New description',
}
user_permissions = ('dcim.view_site', )
@classmethod
def setUpTestData(cls):
@@ -280,6 +281,7 @@ class RackTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'status': 'planned',
}
user_permissions = ('dcim.view_site', )
@classmethod
def setUpTestData(cls):
@@ -368,6 +370,7 @@ class RackReservationTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'description': 'New description',
}
user_permissions = ('dcim.view_rack', 'users.view_user')
@classmethod
def setUpTestData(cls):
@@ -447,6 +450,7 @@ class DeviceTypeTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'part_number': 'ABC123',
}
user_permissions = ('dcim.view_manufacturer', )
@classmethod
def setUpTestData(cls):
@@ -492,6 +496,7 @@ class ModuleTypeTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'part_number': 'ABC123',
}
user_permissions = ('dcim.view_manufacturer', )
@classmethod
def setUpTestData(cls):
@@ -663,6 +668,7 @@ class PowerOutletTemplateTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'description': 'New description',
}
user_permissions = ('dcim.view_devicetype', )
@classmethod
def setUpTestData(cls):
@@ -768,6 +774,7 @@ class FrontPortTemplateTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'description': 'New description',
}
user_permissions = ('dcim.view_rearporttemplate', )
@classmethod
def setUpTestData(cls):
@@ -905,6 +912,7 @@ class ModuleBayTemplateTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'description': 'New description',
}
user_permissions = ('dcim.view_devicetype', )
@classmethod
def setUpTestData(cls):
@@ -945,6 +953,7 @@ class DeviceBayTemplateTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'description': 'New description',
}
user_permissions = ('dcim.view_devicetype', )
@classmethod
def setUpTestData(cls):
@@ -985,6 +994,7 @@ class InventoryItemTemplateTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'description': 'New description',
}
user_permissions = ('dcim.view_devicetype', 'dcim.view_manufacturer',)
@classmethod
def setUpTestData(cls):
@@ -1103,6 +1113,10 @@ class DeviceTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'status': 'failed',
}
user_permissions = (
'dcim.view_site', 'dcim.view_rack', 'dcim.view_location', 'dcim.view_devicerole', 'dcim.view_devicetype',
'extras.view_configtemplate',
)
@classmethod
def setUpTestData(cls):
@@ -1293,6 +1307,7 @@ class ModuleTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'serial': '1234ABCD',
}
user_permissions = ('dcim.view_modulebay', 'dcim.view_moduletype', 'dcim.view_device')
@classmethod
def setUpTestData(cls):
@@ -1358,6 +1373,7 @@ class ConsolePortTest(Mixins.ComponentTraceMixin, APIViewTestCases.APIViewTestCa
'description': 'New description',
}
peer_termination_type = ConsoleServerPort
user_permissions = ('dcim.view_device', )
@classmethod
def setUpTestData(cls):
@@ -1400,6 +1416,7 @@ class ConsoleServerPortTest(Mixins.ComponentTraceMixin, APIViewTestCases.APIView
'description': 'New description',
}
peer_termination_type = ConsolePort
user_permissions = ('dcim.view_device', )
@classmethod
def setUpTestData(cls):
@@ -1442,6 +1459,7 @@ class PowerPortTest(Mixins.ComponentTraceMixin, APIViewTestCases.APIViewTestCase
'description': 'New description',
}
peer_termination_type = PowerOutlet
user_permissions = ('dcim.view_device', )
@classmethod
def setUpTestData(cls):
@@ -1481,6 +1499,7 @@ class PowerOutletTest(Mixins.ComponentTraceMixin, APIViewTestCases.APIViewTestCa
'description': 'New description',
}
peer_termination_type = PowerPort
user_permissions = ('dcim.view_device', )
@classmethod
def setUpTestData(cls):
@@ -1529,6 +1548,7 @@ class InterfaceTest(Mixins.ComponentTraceMixin, APIViewTestCases.APIViewTestCase
'description': 'New description',
}
peer_termination_type = Interface
user_permissions = ('dcim.view_device', )
@classmethod
def setUpTestData(cls):
@@ -1663,6 +1683,7 @@ class FrontPortTest(APIViewTestCases.APIViewTestCase):
'description': 'New description',
}
peer_termination_type = Interface
user_permissions = ('dcim.view_device', 'dcim.view_rearport')
@classmethod
def setUpTestData(cls):
@@ -1721,6 +1742,7 @@ class RearPortTest(APIViewTestCases.APIViewTestCase):
'description': 'New description',
}
peer_termination_type = Interface
user_permissions = ('dcim.view_device', )
@classmethod
def setUpTestData(cls):
@@ -1762,6 +1784,7 @@ class ModuleBayTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'description': 'New description',
}
user_permissions = ('dcim.view_device', )
@classmethod
def setUpTestData(cls):
@@ -1801,6 +1824,7 @@ class DeviceBayTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'description': 'New description',
}
user_permissions = ('dcim.view_device', )
@classmethod
def setUpTestData(cls):
@@ -1864,6 +1888,7 @@ class InventoryItemTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'description': 'New description',
}
user_permissions = ('dcim.view_device', 'dcim.view_manufacturer')
@classmethod
def setUpTestData(cls):
@@ -2160,6 +2185,7 @@ class VirtualChassisTest(APIViewTestCases.APIViewTestCase):
class PowerPanelTest(APIViewTestCases.APIViewTestCase):
model = PowerPanel
brief_fields = ['description', 'display', 'id', 'name', 'powerfeed_count', 'url']
user_permissions = ('dcim.view_site', )
@classmethod
def setUpTestData(cls):
@@ -2212,6 +2238,7 @@ class PowerFeedTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'status': 'planned',
}
user_permissions = ('dcim.view_powerpanel', )
@classmethod
def setUpTestData(cls):

View File

@@ -183,10 +183,13 @@ class ObjectCountsWidget(DashboardWidget):
for model in get_models_from_content_types(self.config['models']):
permission = get_permission_for_model(model, 'view')
if request.user.has_perm(permission):
url = reverse(get_viewname(model, 'list'))
try:
url = reverse(get_viewname(model, 'list'))
except NoReverseMatch:
url = None
qs = model.objects.restrict(request.user, 'view')
# Apply any specified filters
if filters := self.config.get('filters'):
if url and (filters := self.config.get('filters')):
params = dict_to_querydict(filters)
filterset = getattr(resolve(url).func.view_class, 'filterset', None)
qs = filterset(params, qs).qs

View File

@@ -34,7 +34,7 @@ class Command(BaseCommand):
def handle(self, *args, **options):
def _run_script():
def _run_script(script):
"""
Core script execution task. We capture this within a subfunction to allow for conditionally wrapping it with
the event_tracking context manager (which is bypassed if commit == False).
@@ -85,7 +85,6 @@ class Command(BaseCommand):
module_name, script_name = script.split('.', 1)
module, script = get_module_and_script(module_name, script_name)
script = script.python_class
# Take user from command line if provided and exists, other
if options['user']:
@@ -102,7 +101,7 @@ class Command(BaseCommand):
stdouthandler.setLevel(logging.DEBUG)
stdouthandler.setFormatter(formatter)
logger = logging.getLogger(f"netbox.scripts.{script.full_name}")
logger = logging.getLogger(f"netbox.scripts.{script.python_class.full_name}")
logger.addHandler(stdouthandler)
try:
@@ -118,14 +117,14 @@ class Command(BaseCommand):
raise CommandError(f"Invalid log level: {loglevel}")
# Initialize the script form
script = script()
form = script.as_form(data, None)
script_instance = script.python_class()
form = script_instance.as_form(data, None)
# Create the job
job = Job.objects.create(
object=module,
name=script.class_name,
user=User.objects.filter(is_superuser=True).order_by('pk')[0],
object=script,
name=script_instance.class_name,
user=user,
job_id=uuid.uuid4()
)
@@ -149,7 +148,7 @@ class Command(BaseCommand):
# Execute the script. If commit is True, wrap it with the event_tracking context manager to ensure we process
# change logging, webhooks, etc.
with event_tracking(request):
_run_script()
_run_script(script_instance)
else:
logger.error('Data is not valid:')
for field, errors in form.errors.get_json_data().items():

View File

@@ -767,6 +767,7 @@ class FHRPGroupAssignmentTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'priority': 100,
}
user_permissions = ('ipam.view_fhrpgroup', )
@classmethod
def setUpTestData(cls):

View File

@@ -36,6 +36,6 @@ schema = strawberry.Schema(
query=Query,
config=StrawberryConfig(auto_camel_case=False),
extensions=[
DjangoOptimizerExtension,
DjangoOptimizerExtension(prefetch_custom_queryset=True),
]
)

View File

@@ -25,7 +25,7 @@ from utilities.string import trailing_slash
# Environment setup
#
VERSION = '4.0.10'
VERSION = '4.0.11'
HOSTNAME = platform.node()
# Set the base directory two levels up
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

View File

@@ -6,6 +6,7 @@ from rest_framework import status
from core.models import ObjectType
from dcim.models import Site, Location
from ipam.models import ASN, RIR
from users.models import ObjectPermission
from utilities.testing import disable_warnings, APITestCase, TestCase
@@ -45,7 +46,6 @@ class GraphQLTestCase(TestCase):
class GraphQLAPITestCase(APITestCase):
@override_settings(LOGIN_REQUIRED=True)
@override_settings(EXEMPT_VIEW_PERMISSIONS=['*', 'auth.user'])
def test_graphql_filter_objects(self):
"""
Test the operation of filters for GraphQL API requests.
@@ -66,6 +66,7 @@ class GraphQLAPITestCase(APITestCase):
obj_perm.save()
obj_perm.users.add(self.user)
obj_perm.object_types.add(ObjectType.objects.get_for_model(Location))
obj_perm.object_types.add(ObjectType.objects.get_for_model(Site))
# A valid request should return the filtered list
url = reverse('graphql')
@@ -75,6 +76,7 @@ class GraphQLAPITestCase(APITestCase):
data = json.loads(response.content)
self.assertNotIn('errors', data)
self.assertEqual(len(data['data']['location_list']), 1)
self.assertIsNotNone(data['data']['location_list'][0]['site'])
# An invalid request should return an empty list
query = '{location_list(filters: {site_id: "99999"}) {id site {id}}}' # Invalid site ID
@@ -82,3 +84,12 @@ class GraphQLAPITestCase(APITestCase):
self.assertHttpStatus(response, status.HTTP_200_OK)
data = json.loads(response.content)
self.assertEqual(len(data['data']['location_list']), 0)
# Removing the permissions from location should result in an empty locations list
obj_perm.object_types.remove(ObjectType.objects.get_for_model(Location))
query = '{site(id: ' + str(sites[0].pk) + ') {id locations {id}}}'
response = self.client.post(url, data={'query': query}, format="json", **self.header)
self.assertHttpStatus(response, status.HTTP_200_OK)
data = json.loads(response.content)
self.assertNotIn('errors', data)
self.assertEqual(len(data['data']['site']['locations']), 0)

View File

@@ -986,14 +986,7 @@ brace-expansion@^2.0.1:
dependencies:
balanced-match "^1.0.0"
braces@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
dependencies:
fill-range "^7.0.1"
braces@~3.0.2:
braces@^3.0.3, braces@~3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
@@ -1564,7 +1557,7 @@ file-entry-cache@^6.0.1:
dependencies:
flat-cache "^3.0.4"
fill-range@^7.0.1, fill-range@^7.1.1:
fill-range@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
@@ -2174,11 +2167,11 @@ meros@^1.1.4:
integrity sha512-2BNGOimxEz5hmjUG2FwoxCt5HN7BXdaWyFqEwxPTrJzVdABtrL4TiHTcsWSFAxPQ/tOnEaQEJh3qWq71QRMY+w==
micromatch@^4.0.4:
version "4.0.5"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
version "4.0.8"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
dependencies:
braces "^3.0.2"
braces "^3.0.3"
picomatch "^2.3.1"
minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:

View File

@@ -3,7 +3,7 @@
{% if counts %}
<div class="list-group list-group-flush">
{% for model, count, url in counts %}
<a href="{{ url }}" class="list-group-item list-group-item-action px-1 py-2">
<a {% if url %}href="{{ url }}" {% endif %}class="list-group-item list-group-item-action px-1 py-2">
<div class="d-flex w-100 justify-content-between align-items-center">
{{ model|meta:"verbose_name_plural"|bettertitle }}
{% if count is None %}

View File

@@ -210,6 +210,7 @@ class ContactAssignmentTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'priority': ContactPriorityChoices.PRIORITY_INACTIVE,
}
user_permissions = ('tenancy.view_contact', )
@classmethod
def setUpTestData(cls):

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -253,6 +253,7 @@ class VMInterfaceTest(APIViewTestCases.APIViewTestCase):
'description': 'New description',
}
graphql_base_name = 'vm_interface'
user_permissions = ('virtualization.view_virtualmachine', )
@classmethod
def setUpTestData(cls):
@@ -342,6 +343,7 @@ class VirtualDiskTest(APIViewTestCases.APIViewTestCase):
'size': 888,
}
graphql_base_name = 'virtual_disk'
user_permissions = ('virtualization.view_virtualmachine', )
@classmethod
def setUpTestData(cls):

View File

@@ -116,6 +116,7 @@ class TunnelTerminationTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'role': TunnelTerminationRoleChoices.ROLE_PEER,
}
user_permissions = ('vpn.view_tunnel', )
@classmethod
def setUpTestData(cls):
@@ -430,6 +431,7 @@ class IPSecPolicyTest(APIViewTestCases.APIViewTestCase):
class IPSecProfileTest(APIViewTestCases.APIViewTestCase):
model = IPSecProfile
brief_fields = ['description', 'display', 'id', 'name', 'url']
user_permissions = ('vpn.view_ikepolicy', 'vpn.view_ipsecpolicy')
@classmethod
def setUpTestData(cls):
@@ -558,6 +560,7 @@ class L2VPNTest(APIViewTestCases.APIViewTestCase):
class L2VPNTerminationTest(APIViewTestCases.APIViewTestCase):
model = L2VPNTermination
brief_fields = ['display', 'id', 'l2vpn', 'url']
user_permissions = ('dcim.view_location', 'vpn.view_l2vpn')
@classmethod
def setUpTestData(cls):

View File

@@ -114,6 +114,7 @@ class WirelessLinkTest(APIViewTestCases.APIViewTestCase):
bulk_update_data = {
'status': 'planned',
}
user_permissions = ('dcim.view_interface', )
@classmethod
def setUpTestData(cls):

View File

@@ -1,4 +1,4 @@
Django==5.0.8
Django==5.0.9
django-cors-headers==4.4.0
django-debug-toolbar==4.4.6
django-filter==24.2
@@ -8,7 +8,7 @@ django-mptt==0.16.0
django-pglocks==1.0.4
django-prometheus==2.3.1
django-redis==5.4.0
django-rich==1.10.0
django-rich==1.11.0
django-rq==2.10.2
django-taggit==5.0.1
django-tables2==2.7.0
@@ -20,8 +20,8 @@ feedparser==6.0.11
gunicorn==23.0.0
Jinja2==3.1.4
Markdown==3.7
mkdocs-material==9.5.33
mkdocstrings[python-legacy]==0.25.2
mkdocs-material==9.5.34
mkdocstrings[python-legacy]==0.26.0
netaddr==1.3.0
nh3==0.2.18
Pillow==10.4.0
@@ -30,7 +30,7 @@ PyYAML==6.0.2
requests==2.32.3
social-auth-app-django==5.4.2
social-auth-core==4.5.4
strawberry-graphql==0.237.2
strawberry-graphql==0.239.2
strawberry-graphql-django==0.47.1
svgwrite==1.4.3
tablib==3.6.1