infobloxopen / infoblox-client

Infoblox NIOS Python WAPI Client
Apache License 2.0
142 stars 104 forks source link

ARecordBase.create encodes query params incorrectly when an IP is passed instead of a str #347

Open tucked opened 2 years ago

tucked commented 2 years ago
infoblox_client.objects.ARecordBase.create(
    connector,
    name="some.name",
    ip=infoblox_client.objects.IP.create(ip="127.0.0.1"),
)

In 0.5.0:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "venv/lib/python3.8/site-packages/infoblox_client/objects.py", line 334, in create
    cls.create_check_exists(connector,
  File "venv/lib/python3.8/site-packages/infoblox_client/objects.py", line 315, in create_check_exists
    reply = connector.create_object(local_obj.infoblox_type,
  File "venv/lib/python3.8/site-packages/infoblox_client/connector.py", line 50, in callee
    return func(*args, **kwargs)
  File "venv/lib/python3.8/site-packages/infoblox_client/connector.py", line 383, in create_object
    raise exception(
infoblox_client.exceptions.InfobloxCannotCreateObject: Cannot create 'record:a' object(s): b'{ "Error": "AdmConProtoError: Invalid value for ipv4addr: {\\"ipv4addr\\": \\"127.0.0.1\\"}: Must be string type", \n  "code": "Client.Ibap.Proto", \n  "text": "Invalid value for ipv4addr: {\\"ipv4addr\\": \\"127.0.0.1\\"}: Must be string type"\n}' [code 400]

In 0.5.1:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "venv/lib/python3.8/site-packages/infoblox_client/objects.py", line 370, in create
    cls.create_check_exists(connector,
  File "venv/lib/python3.8/site-packages/infoblox_client/objects.py", line 316, in create_check_exists
    if local_obj.fetch(only_ref=True):
  File "venv/lib/python3.8/site-packages/infoblox_client/objects.py", line 439, in fetch
    reply = self.connector.get_object(self.infoblox_type,
  File "venv/lib/python3.8/site-packages/infoblox_client/connector.py", line 56, in callee
    raise ib_ex.InfobloxConnectionError(reason=e)
infoblox_client.exceptions.InfobloxConnectionError: Infoblox HTTP request failed with: 400 Client Error: Bad Request for url: https://infoblox.domain.local/wapi/v2.10/record%3Aa?ipv4addr=ipv4addr&name=some.name&_proxy_search=GM        

Note that ?ipv4addr=ipv4addr& should be ?ipv4addr=127.0.0.1&.

I haven't pinpointed the issue, but I suspect it's somewhere around here: https://github.com/infobloxopen/infoblox-client/blob/bff3a6613b918d2d0d4e4cc989d6c964f5aac1a4/infoblox_client/objects.py#L290

Maybe IP should override to_dict?

(Pdb) pp self.field_to_dict("name")
'some.name'
(Pdb) pp type(self.ipv4addr)
<class 'infoblox_client.objects.IPv4'>
(Pdb) pp self.field_to_dict("ipv4addr")
{'ipv4addr': '127.0.0.1'}

The difference between 0.5.0 and 0.5.1 is likely due to https://github.com/infobloxopen/infoblox-client/commit/2e462ca54a9c14cb4643e2f9bcb6e9cc9bb61778:

(Pdb) pp query_params
{'ipv4addr': {'ipv4addr': '127.0.0.1'},
 'name': 'some.name'}
(Pdb) pp self._urlencode(query_params, doseq=False)
'ipv4addr=%7B%27ipv4addr%27%3A+%27127.0.0.1%27%7D&name=some.name'
(Pdb) pp self._urlencode(query_params, doseq=True)
'ipv4addr=ipv4addr&name=some.name'

Side note: why don't we use the params kwarg provided by requests.post?

Workaround:

infoblox_client.objects.ARecordBase.create(
    connector,
    name="some.name",
    ip="127.0.0.1",
)
sarya-infoblox commented 2 years ago

Hi @tucked

We are working on a priority ticket as of now and will look into this issue as soon as I get some time.