jagter/python-netbox

Not handling plus signs in generated URLs.

Closed this issue · 1 comments

Affected functions:

  • dcim.create_device
  • dcim.get_device_types

If the device type contains a plus sign (in my case https://mikrotik.com/product/CCR1016-12S-1Splus), the call does not error out but fails to find the data in netbox, looking into it the following URL is generated:
GET /api/dcim/device-types/?model=CCR1016-12S-1S+&limit=0 HTTP/1.1\r\n

Where it should be generating this:
GET /api/dcim/device-types/?model=CCR1016-12S-1S%2B&limit=0

import logging
import urllib.parse
from netbox import NetBox

LOGGING_FORMAT = '%(asctime)s - %(name)s - %(thread)d - %(levelname)s - %(message)s'
logging.basicConfig(level = logging.DEBUG, format=LOGGING_FORMAT, filename = 'output.txt')

m = 'CCR1016-12S-1S+'
n = NetBox(host='172.16.0.22', port=8000, use_ssl=False, auth_token='<auth token>')

unquoted = n.dcim.get_device_types(model=m)
logging.debug("Unquoted: {0}".format(unquoted))

quoted = n.dcim.get_device_types(model=urllib.parse.quote(m))
logging.debug("Unquoted: {0}".format(quoted))

Output file contents:

2021-04-08 03:06:31,712 - urllib3.connectionpool - 139725271254848 - DEBUG - Starting new HTTP connection (1): 172.16.0.22:8000
2021-04-08 03:06:33,391 - urllib3.connectionpool - 139725271254848 - DEBUG - http://172.16.0.22:8000 "GET /api/dcim/device-types/?model=CCR1016-12S-1S+&limit=0 HTTP/1.1" 200 52
2021-04-08 03:06:33,395 - root - 139725271254848 - DEBUG - Unquoted: []
2021-04-08 03:06:33,398 - urllib3.connectionpool - 139725271254848 - DEBUG - Starting new HTTP connection (1): 172.16.0.22:8000
2021-04-08 03:06:33,532 - urllib3.connectionpool - 139725271254848 - DEBUG - http://172.16.0.22:8000 "GET /api/dcim/device-types/?model=CCR1016-12S-1S%2B&limit=0 HTTP/1.1" 200 576
2021-04-08 03:06:33,535 - root - 139725271254848 - DEBUG - Unquoted: [{'id': 803, 'url': 'http://172.16.0.22:8000/api/dcim/device-types/803/', 'manufacturer': {'id': 49, 'url': 'http://172.16.0.22:8000/api/dcim/manufacturers/49/', 'name': 'MikroTik', 'slug': 'mikrotik'}, 'model': 'CCR1016-12S-1S+', 'slug': 'ccr1016-12s-1splus', 'display_name': 'MikroTik CCR1016-12S-1S+', 'part_number': '', 'u_height': 1, 'is_full_depth': False, 'subdevice_role': None, 'front_image': None, 'rear_image': None, 'comments': '', 'tags': [], 'custom_fields': {}, 'created': '2021-04-07', 'last_updated': '2021-04-07T18:20:59.123550Z', 'device_count': 1}]

Workaround:
Manually quote the appropriate entries.

Notes:
I believe this may affect many more functions as the create also needs to be pre-quoted to handle the create for a device_type containing a plus sign as the data is in the POST body, my fixed code is as follows:

rez = self._netbox.dcim.create_device(
	name        = dev_facts['hostname'],
	device_role = 'router',
	site_name   = location_code,
	device_type = urllib.parse.quote(dev_type[0]['model']),
	serial      = dev_facts['serial_number'],
)

I am guessing the best place to handle this would be __request in netbox/connection.py but we at least need to handle if the plus was placed there to replace a space in the URL or if it was part of the data itself.

Hi,

First of all, thanks for your well described issue. The issue is fixed in 0.0.20 released a couple of minutes ago.