-
Notifications
You must be signed in to change notification settings - Fork 218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inventory performance improvements and fixes fetching interfaces and services #202
Inventory performance improvements and fixes fetching interfaces and services #202
Conversation
netbox-community/netbox#4313 removed id__in as you can acheive the same by listing id multiple times.
… interfaces/services. A side effect is it resolves netbox-community#142 fetching services for VMs Includes better support virtual chasis - only take the master device and not the children. Some of this from ansible/ansible#60642 See the TODO comments for work still to be done before being ready to merge.
* Allow tuning for largest size permitted by your webserver, for optimum performance reducing number of required HTTP requests. * Handle exceptions from within threads and raise on the main thread after being joined. This ensures that any HTTP errors from refresh_ methods will stop execution of the rest of the plugin. For example, you'll notice if you receive a HTTP 414 URI Too Long. Added unit tests for these things.
… as they may change every commit.
Also added example of useful device_query_filters
I think I've improved this enough to add my name to it.
I found in my install I was getting HTTP 400 errors with 8000 length. 4000 length works. May depend on web server, CDN, etc.
Looks like adding the extra interfaces to the test data broke the integration tests and IDs have changed. Tomorrow I think I'll fix this by updating |
e6465d7
to
3df3078
Compare
3df3078
to
bc58f55
Compare
Netbox 2.6 seems to return these in a different order than 2.7 and 2.8. Order shouldn't be important.
I've almost finished fixing the tests. The issue I've run into is that Netbox 2.6 doesn't support querying for multiple device ids at the same time (eg. http://localhost:32768/api/ipam/ip-addresses/?limit=0&assigned_to_interface=true&device_id=1&device_id=4 returns only the IPs for device id 4, and not for 1) This can be fixed by setting the new I'm not sure whether we want to:
|
* Gets the API version, to allow working around netbox-community/netbox#3507 in tests * While I'm at it, it also allows fetching allowed_device_query_parameters dynamically instead of hard-coding the list.
…_uri_length: 0 When fetching interfaces of virtual-chassis child devices in a separate request to the master, the interfaces will be returned twice. Converted some lists to dicts to efficiently check if the interface ID already exists. Made same change for services and IP Addresses, in case they have similar issues.
fa92ddb
to
add5fe8
Compare
Ok this is ready for review now. When tracking down the issue with the tests on NetBox 2.6, I discovered that netbox-community/netbox#3507 is the cause and was only fixed in v2.7.5. I also came across an edge case I hadn't handled - when |
Fixes #142 #143
Implements #199 #200
(Replaces closed pull request #196)
Refactors how interfaces, ip addresses and services are fetched.
Overview
Introduces two new options:
fetch_all
- when fetching interfaces, services, and IPs should all be fetched, or should the plugin filter on device/vm idsmax_uri_length
- maximum length of a GET request. Affects how many&device_id=1&device_id=2
etc. can fit into a single request.The previous flow:
New flow:
fetch_all
isTrue
(default), get all. Otherwise only request for specific hostsfetch_all
is True, get all IPs. Otherwise, if any of a host's interfaces havecount_ipaddresses
> 0, then fetch IPs for those hostsDetails
Issue #142 is solved by always querying for VMs and devices by ID and not name. Names are never passed in URLs anymore so there'll be no issues with spaces, or duplicate names. I also decided #199 to add a host var
is_virtual
to clearly declare whether a host is a device or vm. This is used in logic about whether a host id should be passed into a device or vm NetBox API.There's 2 different ways I've optimised fetching interfaces/ips/services, controlled by the
fetch_all
option as differentquery_filter
options will determine which method will have the fastest result.fetch_all: True
- all interfaces, IPs that areassigned_to_interface=true
, and all services are requested from NetBox. This will give the fastest result when you are requesting all hosts (ie. there are noquery_filters
)fetch_all: False
- interfaces and services are fetched only for specific hosts, appending&device_id=X
or&virtual_machine_id=X
to the requests. The optimisation here is that you can pass multiple IDs to a single request to reduce HTTP and server-side overhead. The newmax_uri_length
setting determines how many of these IDs will be passed into a single request. For reference, different versions of Internet Explorer is limited to somewhere around 1-2k. Chrome appears to have no limit. Apache server defaults to 8190, AWS ALB is limited to 8K. In reality I found I was getting a HTTP 400 error if I went much above 4K, so I decided 4000 was a sensible default. Users may lower this limit if their particular server won't accept these long requests.Another change is the handling of virtual chassis #200. Previously child devices were returned as separate hosts. As the whole point of a virtual chassis is to represent devices that share a control plane, for the purpose of Ansible users you should not ever need to connect to child devices as individual hosts. A pull request ansible/ansible#60642 by @Yannis100 proposed removing child devices and I agree it makes sense.
I made that change as part of this pull request as it affects the logic of looking up a device's interfaces. Interfaces that belong to child devices will appear as part of the master device as in the Netbox UI and APIs.
Performance tests #143
Our corporate NetBox has grown since I last did these tests - now have 2515 devices, 3333 IPs, and 12202 interfaces.
All tests have
interfaces: True
andservices: True
0.2.0
releasefetch_all: True
(default)fetch_all: False
So this is roughly a 10x improvement!
fetch_all:True
is the fastest in the default case.With
query_filters
It's also interesting to test the case with some
query_filters
defined. We usually usedevice_query_filters: - has_primary_ip: 'true'
as our NetBox has many passive devices (eg. patch panels) that Ansible does not care about. In this case:0.2.0
releasefetch_all: True
(default)fetch_all: False
It's interesting in this case that
fetch_all: False
is the fastest, and only request 2 extra HTTP requests. The requests return quicker as there's much less data.Other minor changes