mirror of
https://github.com/netbox-community/netbox.git
synced 2026-01-11 21:10:29 +01:00
gunicorn spends 80% of each request in get_object_permissions() #5445
Closed
opened 2025-12-29 19:28:04 +01:00 by adam
·
21 comments
No Branch/Tag Specified
main
update-changelog-comments-docs
feature-removal-issue-type
20911-dropdown
20239-plugin-menu-classes-mutable-state
21097-graphql-id-lookups
feature
fix_module_substitution
20923-dcim-templates
20044-elevation-stuck-lightmode
feature-ip-prefix-link
v4.5-beta1-release
20068-import-moduletype-attrs
20766-fix-german-translation-code-literals
20378-del-script
7604-filter-modifiers-v3
circuit-swap
12318-case-insensitive-uniqueness
20637-improve-device-q-filter
20660-script-load
19724-graphql
20614-update-ruff
14884-script
02496-max-page
19720-macaddress-interface-generic-relation
19408-circuit-terminations-export-templates
20203-openapi-check
fix-19669-api-image-download
7604-filter-modifiers
19275-fixes-interface-bulk-edit
fix-17794-get_field_value_return_list
11507-show-aggregate-and-rir-on-api
9583-add_column_specific_search_field_to_tables
v4.5.0
v4.4.10
v4.4.9
v4.5.0-beta1
v4.4.8
v4.4.7
v4.4.6
v4.4.5
v4.4.4
v4.4.3
v4.4.2
v4.4.1
v4.4.0
v4.3.7
v4.4.0-beta1
v4.3.6
v4.3.5
v4.3.4
v4.3.3
v4.3.2
v4.3.1
v4.3.0
v4.2.9
v4.3.0-beta2
v4.2.8
v4.3.0-beta1
v4.2.7
v4.2.6
v4.2.5
v4.2.4
v4.2.3
v4.2.2
v4.2.1
v4.2.0
v4.1.11
v4.1.10
v4.1.9
v4.1.8
v4.2-beta1
v4.1.7
v4.1.6
v4.1.5
v4.1.4
v4.1.3
v4.1.2
v4.1.1
v4.1.0
v4.0.11
v4.0.10
v4.0.9
v4.1-beta1
v4.0.8
v4.0.7
v4.0.6
v4.0.5
v4.0.3
v4.0.2
v4.0.1
v4.0.0
v3.7.8
v3.7.7
v4.0-beta2
v3.7.6
v3.7.5
v4.0-beta1
v3.7.4
v3.7.3
v3.7.2
v3.7.1
v3.7.0
v3.6.9
v3.6.8
v3.6.7
v3.7-beta1
v3.6.6
v3.6.5
v3.6.4
v3.6.3
v3.6.2
v3.6.1
v3.6.0
v3.5.9
v3.6-beta2
v3.5.8
v3.6-beta1
v3.5.7
v3.5.6
v3.5.5
v3.5.4
v3.5.3
v3.5.2
v3.5.1
v3.5.0
v3.4.10
v3.4.9
v3.5-beta2
v3.4.8
v3.5-beta1
v3.4.7
v3.4.6
v3.4.5
v3.4.4
v3.4.3
v3.4.2
v3.4.1
v3.4.0
v3.3.10
v3.3.9
v3.4-beta1
v3.3.8
v3.3.7
v3.3.6
v3.3.5
v3.3.4
v3.3.3
v3.3.2
v3.3.1
v3.3.0
v3.2.9
v3.2.8
v3.3-beta2
v3.2.7
v3.3-beta1
v3.2.6
v3.2.5
v3.2.4
v3.2.3
v3.2.2
v3.2.1
v3.2.0
v3.1.11
v3.1.10
v3.2-beta2
v3.1.9
v3.2-beta1
v3.1.8
v3.1.7
v3.1.6
v3.1.5
v3.1.4
v3.1.3
v3.1.2
v3.1.1
v3.1.0
v3.0.12
v3.0.11
v3.0.10
v3.1-beta1
v3.0.9
v3.0.8
v3.0.7
v3.0.6
v3.0.5
v3.0.4
v3.0.3
v3.0.2
v3.0.1
v3.0.0
v2.11.12
v3.0-beta2
v2.11.11
v2.11.10
v3.0-beta1
v2.11.9
v2.11.8
v2.11.7
v2.11.6
v2.11.5
v2.11.4
v2.11.3
v2.11.2
v2.11.1
v2.11.0
v2.10.10
v2.10.9
v2.11-beta1
v2.10.8
v2.10.7
v2.10.6
v2.10.5
v2.10.4
v2.10.3
v2.10.2
v2.10.1
v2.10.0
v2.9.11
v2.10-beta2
v2.9.10
v2.10-beta1
v2.9.9
v2.9.8
v2.9.7
v2.9.6
v2.9.5
v2.9.4
v2.9.3
v2.9.2
v2.9.1
v2.9.0
v2.9-beta2
v2.8.9
v2.9-beta1
v2.8.8
v2.8.7
v2.8.6
v2.8.5
v2.8.4
v2.8.3
v2.8.2
v2.8.1
v2.8.0
v2.7.12
v2.7.11
v2.7.10
v2.7.9
v2.7.8
v2.7.7
v2.7.6
v2.7.5
v2.7.4
v2.7.3
v2.7.2
v2.7.1
v2.7.0
v2.6.12
v2.6.11
v2.6.10
v2.6.9
v2.7-beta1
Solcon-2020-01-06
v2.6.8
v2.6.7
v2.6.6
v2.6.5
v2.6.4
v2.6.3
v2.6.2
v2.6.1
v2.6.0
v2.5.13
v2.5.12
v2.6-beta1
v2.5.11
v2.5.10
v2.5.9
v2.5.8
v2.5.7
v2.5.6
v2.5.5
v2.5.4
v2.5.3
v2.5.2
v2.5.1
v2.5.0
v2.4.9
v2.5-beta2
v2.4.8
v2.5-beta1
v2.4.7
v2.4.6
v2.4.5
v2.4.4
v2.4.3
v2.4.2
v2.4.1
v2.4.0
v2.3.7
v2.4-beta1
v2.3.6
v2.3.5
v2.3.4
v2.3.3
v2.3.2
v2.3.1
v2.3.0
v2.2.10
v2.3-beta2
v2.2.9
v2.3-beta1
v2.2.8
v2.2.7
v2.2.6
v2.2.5
v2.2.4
v2.2.3
v2.2.2
v2.2.1
v2.2.0
v2.1.6
v2.2-beta2
v2.1.5
v2.2-beta1
v2.1.4
v2.1.3
v2.1.2
v2.1.1
v2.1.0
v2.0.10
v2.1-beta1
v2.0.9
v2.0.8
v2.0.7
v2.0.6
v2.0.5
v2.0.4
v2.0.3
v2.0.2
v2.0.1
v2.0.0
v2.0-beta3
v1.9.6
v1.9.5
v2.0-beta2
v1.9.4-r1
v1.9.3
v2.0-beta1
v1.9.2
v1.9.1
v1.9.0-r1
v1.8.4
v1.8.3
v1.8.2
v1.8.1
v1.8.0
v1.7.3
v1.7.2-r1
v1.7.1
v1.7.0
v1.6.3
v1.6.2-r1
v1.6.1-r1
1.6.1
v1.6.0
v1.5.2
v1.5.1
v1.5.0
v1.4.2
v1.4.1
v1.4.0
v1.3.2
v1.3.1
v1.3.0
v1.2.2
v1.2.1
v1.2.0
v1.1.0
v1.0.7-r1
v1.0.7
v1.0.6
v1.0.5
v1.0.4
v1.0.3-r1
v1.0.3
1.0.0
Labels
Clear labels
beta
breaking change
complexity: high
complexity: low
complexity: medium
needs milestone
netbox
pending closure
plugin candidate
pull-request
severity: high
severity: low
severity: medium
status: accepted
status: backlog
status: blocked
status: duplicate
status: needs owner
status: needs triage
status: revisions needed
status: under review
topic: GraphQL
topic: Internationalization
topic: OpenAPI
topic: UI/UX
topic: cabling
topic: event rules
topic: htmx navigation
topic: industrialization
topic: migrations
topic: plugins
topic: scripts
topic: templating
topic: testing
type: bug
type: deprecation
type: documentation
type: feature
type: housekeeping
type: translation
Mirrored from GitHub Pull Request
Milestone
No items
No Milestone
Projects
Clear projects
No project
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: starred/netbox#5445
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @heroin-moose on GitHub (Sep 30, 2021).
NetBox version
v3.0.3
Python version
3.9
Steps to Reproduce
Expected Behavior
The request should be completed way faster.
Observed Behavior
For me the situtation looks like this: the HTTP request takes ~1.6s to complete and ~1.3s of that request was spent in authentication.py:get_object_permissions(). I am terrible with Python, but I came up with a patch:
The output:
Wow. That's a lot. Okay, more dirty patching:
And now I have this:
Still a lot (the request itself took ~400ms), but a lot better.
I'm not familiar with Netbox internals at all, so I'm not sure where to start digging.
@jeremystretch commented on GitHub (Sep 30, 2021):
Nice sleuthing! This looks related to (if not the same root issue as) #6926. Do you agree?
Also, can you confirm whether this is reproducible using local authentication, or only as an LDAP user?
@heroin-moose commented on GitHub (Sep 30, 2021):
I'm not sure, but looks related. AUTH_LDAP_FIND_GROUP_PERMS does not help me either.
Can I enable both AD and local?
@jeremystretch commented on GitHub (Sep 30, 2021):
Sure. I mean, does it happen if you log in as a user with a local NetBox account? (One defined under admin > users.)
@heroin-moose commented on GitHub (Sep 30, 2021):
Trying to remember the password for netbox user...
@heroin-moose commented on GitHub (Sep 30, 2021):
No, it does not happen, NetBox is much more responsive and this function is not called at all.
@heroin-moose commented on GitHub (Sep 30, 2021):
Any other info you need?
@kkthxbye-code commented on GitHub (Sep 30, 2021):
To add to this, we experienced probably the same problem. I didn't have time to debug the issue, but for us it was caused by the way our permissions were structured.
We had a netbox-user and a netbox-admin group mapped by LDAP. Each group had an individual object permission for view, change, delete:
etc.
These were assigned to the groups (all of the for the admin group and all except adminish tasks for the other group). These permissions were created by netbox at one point (or netbox_docker?) at around v2.7, but netbox does not seem to seed the permissions anymore on fresh installs. I solved the issue on our end by just creating two larger permissions, one called all_permissions and one all_permissions_except_admin, then response time was fast for both local and ldap users.
In summation, the issue with our deployment was pre-seeded individual object permissions assigned to the mapped ldap group (around 300 permissions I think).
@heroin-moose commented on GitHub (Sep 30, 2021):
If I do understand correctly the root issue is not the fact that
get_object_permissions()loops 10k times. The problem is that it does so on every request (i.e. it's not cached). Am I right, @jeremystretch?@heroin-moose commented on GitHub (Oct 18, 2021):
So, anything else I can do to help you fix this?
@jeremystretch commented on GitHub (Oct 18, 2021):
@heroin-moose you're certainly welcome to volunteer a fix, if you can identify one that doesn't break the behavior of permissions.
@heroin-moose commented on GitHub (Oct 18, 2021):
Can you describe the intended algorithm behind this function? Is my assumption that it shall not called on each request, but cached instead, correct?
@jeremystretch commented on GitHub (Oct 18, 2021):
I'm sorry, I don't have any time to budget on this particular problem right now. Maybe you can track down the person who wrote it.
@heroin-moose commented on GitHub (Oct 18, 2021):
Okay, got ya.
@xkilian commented on GitHub (Oct 18, 2021):
My collegue tracked down that the LDAP integration has a backwards implementation in Django for how to query groups. It first does a query using a service account and then queries to get all groups, then it looks for the user in the groups, then tries to match groups to Netbox groups. (bad design DJANGO side)
My collegue modified it(Django LDAP module) so that it uses the actuel user for the request and returns if it is a valid user, then netbox does the group mapping based on the user. We do not currently need groups to come from AD, but he will eventually modify it to do the initial query using the user and also request what groups the user is a member of. (We already do this internally in python using a reverse proxy web app in another project)
There is already someone that posted some code (pull request) to modify the LDAP DJANGO code to do the first part and it works well. (Ended up writing the same code as was published on the internet, so it is good and works.) I do not have a link, but a little googling should find it.
Anyway, this should improve overall speed in addition to any Netbox related optimizations.
Cheers.
@buzzingbren commented on GitHub (Oct 25, 2021):
I don't have a solution. I ran into this as well with our setup. Using LDAP against an Active Directory, on its own works just fine.
But we're using https://github.com/bb-Ricardo/netbox-sync for filling our Netbox with data. And yes I know, the use case for Netbox is the other way as the source of truth. But for our little environment (4 ESX clusters in 4 separate sites) this just works better than an Excel Spreadsheet.
During synchronization Netbox-Sync uses the API to request info from Netbox and Update/Add info to Netbox.
But this "bug" (for us then) slowed it down to a halt (resulting in 500 Internal Server errors) since version 3.0.x.
We've now just disabled LDAP, because this was the only way for us. Even though the token was of a local defined user, it still screeched to a halt and was unworkable.
We're lucky that we're only a small team, so it's not a real issue to forgo the LDAP integration. But it would be nice to use again in the future.
@lastorel commented on GitHub (Oct 27, 2021):
The same situation. Kibana find ~70000 logs from LDAP server when cron starts my sync tasks...
@kkthxbye-code commented on GitHub (Oct 28, 2021):
Please check out the proposed fix in #7676. Note that issues like @lasorel posted are not the same, as this issue and the fix only address CPU usage. Caching issues should be raised in issue #6926
@DanSheps commented on GitHub (Oct 29, 2021):
Could you link to the django issue?
@xkilian commented on GitHub (Oct 29, 2021):
DJANGO LDAP AUTH
Using memberof for the given user instead of querying group members and looking for the user in the returned data dump.
@xkilian commented on GitHub (Oct 29, 2021):
3 keys points:
django_auth_ldap, this does not require group search to be configured.@xkilian commented on GitHub (Nov 3, 2021):
This is the pull request: https://github.com/django-auth-ldap/django-auth-ldap/pull/180