DanSheps / netbox-routing

A Netbox Routing plugin
Apache License 2.0
50 stars 6 forks source link

Swagger UI breaks with AssertionError #50

Closed lukassavukaitis closed 1 week ago

lukassavukaitis commented 4 weeks ago

Plugin version

v0.2.3

NetBox version

v4.1.2

Python version

3.12

Steps to Reproduce

Trying to load Swagger UI I'm getting Internal Server Error: /api/schema/ Disabling the plugin in configuration.py and restarting netbox service, and re-enabling plugin again resolves it, but after few days it breaks again.

Expected Behavior

Swagger UI opens fine.

Observed Behavior

AssertionError: The field 'settings' was declared on serializer BGPRouterSerializer, but has not been included in the 'fields' option. is thrown in netbox log.

Full log message:

2024-10-18 07:54:48,608 django.request ERROR: Internal Server Error: /api/schema/
Traceback (most recent call last):
  File "/opt/netbox/venv/lib64/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/django/utils/decorators.py", line 188, in _view_wrapper
    result = _process_exception(request, e)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/django/utils/decorators.py", line 186, in _view_wrapper
    response = view_func(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper
    return view_func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/django/views/generic/base.py", line 104, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/opt/netbox/venv/lib64/python3.12/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/opt/netbox/venv/lib64/python3.12/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/drf_spectacular/views.py", line 84, in get
    return self._get_schema_response(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/drf_spectacular/views.py", line 92, in _get_schema_response
    data=generator.get_schema(request=request, public=self.serve_public),
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/drf_spectacular/generators.py", line 285, in get_schema
    paths=self.parse(request, public),
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/drf_spectacular/generators.py", line 256, in parse
    operation = view.schema.get_operation(
                ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/drf_spectacular/openapi.py", line 112, in get_operation
    operation['responses'] = self._get_response_bodies()
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/drf_spectacular/openapi.py", line 1374, in _get_response_bodies
    return {'200': self._get_response_for_code(response_serializers, '200', direction=direction)}
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/drf_spectacular/openapi.py", line 1430, in _get_response_for_code
    component = self.resolve_serializer(serializer, direction)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/drf_spectacular/openapi.py", line 1614, in resolve_serializer
    component.schema = self._map_serializer(serializer, direction, bypass_extensions)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/drf_spectacular/openapi.py", line 930, in _map_serializer
    schema = self._map_basic_serializer(serializer, direction)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/drf_spectacular/openapi.py", line 1029, in _map_basic_serializer
    schema = self._map_serializer_field(field, direction)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/drf_spectacular/openapi.py", line 675, in _map_serializer_field
    component = self.resolve_serializer(field, direction)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/drf_spectacular/openapi.py", line 1614, in resolve_serializer
    component.schema = self._map_serializer(serializer, direction, bypass_extensions)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/drf_spectacular/openapi.py", line 930, in _map_serializer
    schema = self._map_basic_serializer(serializer, direction)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/drf_spectacular/openapi.py", line 1029, in _map_basic_serializer
    schema = self._map_serializer_field(field, direction)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/drf_spectacular/openapi.py", line 675, in _map_serializer_field
    component = self.resolve_serializer(field, direction)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/drf_spectacular/openapi.py", line 1614, in resolve_serializer
    component.schema = self._map_serializer(serializer, direction, bypass_extensions)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/drf_spectacular/openapi.py", line 930, in _map_serializer
    schema = self._map_basic_serializer(serializer, direction)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/drf_spectacular/openapi.py", line 1023, in _map_basic_serializer
    for field in serializer.fields.values():
                 ^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.12/functools.py", line 995, in __get__
    val = self.func(instance)
          ^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/netbox/netbox/api/serializers/base.py", line 61, in fields
    return super().fields
           ^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/django/utils/functional.py", line 47, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
                                         ^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/rest_framework/serializers.py", line 372, in fields
    for key, value in self.get_fields().items():
                      ^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/rest_framework/serializers.py", line 1079, in get_fields
    field_names = self.get_field_names(declared_fields, info)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/netbox/venv/lib64/python3.12/site-packages/rest_framework/serializers.py", line 1175, in get_field_names
    assert field_name in fields, (
AssertionError: The field 'settings' was declared on serializer BGPRouterSerializer, but has not been included in the 'fields' option.