Reply

Issue with entering payload data with lists and dictionaries

Guru
Posts: 26
3775     1

I'm attempting to use the WAPI with python to create some networks and ranges.  Instead of simply creating them, which is trivial, I'm trying to fully populate them with all of their piece parts, such as extensible attributes, dhcp_members, and DHCP options.  In the past, I've used the infoblox python library to create a network and then update it's extattrs, but that was a two step operation.  I'd prefer to do it all in one step.

 

When I retrieve a dhcpmember field from an existing network object, I am presented with something that looks like this:

'members': 
	[
	{'_struct': 'dhcpmember', 'ipv4addr': '10.20.200.53', 'ipv6addr': None, 'name': 'dnstsrv1.example.com'}, 
	{'_struct': 'dhcpmember', 'ipv4addr': '10.20.100.53', 'ipv6addr': None, 'name': 'dnsksrv1.example.com'}
	]

However, if I try to write this field via a POST while creating a new network object, I'm informed that: 

 

infoblox.InfobloxGeneralException: Arguments can not be repeated (members)

I don't think the issue is limited to the members list, as the options list and extensible attributes dictionary seems to present the same error message.  My guess is that there is some trick needed for encoding the embedded list/dict correctly.  Anybody does this successfully?

 

Actual code and data example:

#
# in infoblox library
def create_network(self, network, payload): ''' Implements IBA REST API call to create DHCP network object :param network: network in CIDR format ''' rest_url = 'https://' + self.iba_host + '/wapi/v' + self.iba_wapi_version + '/network' print('\nURL:',rest_url) print('Payload:',payload) try: r = requests.post(url=rest_url, auth=(self.iba_user, self.iba_password), verify=self.iba_verify_ssl, data=payload) r_json = r.json() print(r.status_code) if r.status_code == 200 or r.status_code == 201: return else: if 'text' in r_json: raise InfobloxGeneralException(r_json['text']) else: r.raise_for_status() except ValueError: raise Exception(r) except Exception: raise iblx = infoblox.Infoblox(<SERVER>, <USER>, <PASSWORD>, <VERSION>, <DNS_VIEW>, <NETWORK_VIEW>,False) payload= { 'network': '10.208.100.0/22', 'network_view': 'default', 'comment': 'test network for creating scripts', 'discovery_member': 'ibnd.example.com', 'enable_discovery': True, 'extattrs': { 'Building': {'value': 'K'}, 'DHCP': {'value': 'Y'}, 'Date Assigned': {'value': '2/8/2019'}, 'Disposition': {'value': 'ACTIVE'}, 'Floor(s)': {'value': '2'}, 'Interface': {'value': 'Vlan100'}, 'Legacy VLAN': {'value': 100}, 'Location': {'value': 'BR549'}, 'Renewal Date': {'value': '2/8/2021'}, 'Service': {'value': 'VOIP'}, 'Site': {'value': 'Bedford Falls'}, 'Source': {'value': 'NewPopulateNetworks.py'}, 'Switch': {'value': 'switch1'}, 'Tech': {'value': 'fitz@example.com'}, 'Usage': {'value': 'Prod'}, 'Zone': {'value': 'Internet (*default)'} }, 'members': [ {'_struct': 'dhcpmember', 'ipv4addr': '10.20.200.53', 'ipv6addr': None, 'name': 'dnstsrv1.example.com'}, {'_struct': 'dhcpmember', 'ipv4addr': '10.20.100.53', 'ipv6addr': None, 'name': 'dnsksrv1.example.com'} ], 'options': [ {'name': 'routers', 'num': 3, 'use_option': True, 'value': 'xx.xx.xx.1', 'vendor_class': 'DHCP'}, {'name': 'domain-name-servers', 'num': 6, 'use_option': False, 'value': '10.20.100.53,10.20.200.53', 'vendor_class': 'DHCP'}, {'name': 'domain-name', 'num': 15, 'use_option': True, 'value': 'example.com', 'vendor_class': 'DHCP'}, {'name': 'ntp-servers', 'num': 42, 'value': '10.20.100.53,10.20.200.53', 'vendor_class': 'DHCP'}, {'name': 'dhcp-lease-time', 'num': 51, 'use_option': False, 'value': '38400', 'vendor_class': 'DHCP'}, {'name': 'tftp-server-name', 'num': 66, 'value': '10.10.10.10/testdir', 'vendor_class': 'DHCP'}, {'name': 'option-242', 'num': 242, 'value': 'MCIPADD=10.20.30.40,HTTPSRVR=10.20.20.40,HTTPDIR=master,L2Q=1,L2QVLAN=720', 'vendor_class': 'DHCP'} ] } fred = iblx.create_network2(network,payload)

If I remove 'extattrs', 'members', and 'options',from payload,  the create works just fine.If I leave any one of them, it fails.

Re: Issue with entering payload data with lists and dictionaries

Adviser
Posts: 33
3775     1

Did you ever get a response to this question? I had the very same issue myself with one of my scripts, and after much investigation discovered that the trick is very simple: when you do requests.post(), use json=payload instead of data=payload. Apparently when you use data= it does not correctly encode the data for transmission. (It apparently handles simple parameters ok, but fails when you embed a list of dictionaries within the data.

Showing results for 
Search instead for 
Did you mean: 

Recommended for You