dnaeon / pyinfoblox

Infoblox WAPI module for Python

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to set/update extattrs?

philipsd6 opened this issue · comments

Unless I am missing something, it doesn't seem possible to create, or update an object with extensible attributes.

With this valid extattrs structure:

attributes = {'Description': {'value': 'Set extensible attributes via API'},
              'Editor':      {'value': 'philipsd6'}}

Accessing pyinfoblox internals, this works:

infoblox = InfobloxWAPI(**connect_data)
import json
r = infoblox.session.put(infoblox.wapi + objref,
                         data=json.JSONEncoder().encode({'extattrs':attributes}))
r.content

'"fixedaddress/ZG5zLmZpaGEkY2FkAHJ5c3MkMTcyLjI0Ljg3Ljg5LjAuLg:10.10.10.10/default"'

But this doesn't:

infoblox.fixedaddress.update(objref, extattrs=attributes)

InfobloxWAPIException: { "Error": "AdmConProtoError: Arguments can not be repeated (extattrs)", 
  "code": "Client.Ibap.Proto", 
  "text": "Arguments can not be repeated (extattrs)"
}

Nor does this:

infoblox.fixedaddress.update(objref, extattrs=json.JSONEncoder().encode(attributes))

InfobloxWAPIException: { "Error": "AdmConProtoError: Error converting argument extattrs: Type not supported in query string", 
  "code": "Client.Ibap.Proto", 
  "text": "Error converting argument extattrs: Type not supported in query string"
}

Hey Phillip,

I've just pushed a fix for this to the master branch of pyinfoblox.

Here is an example how to get and update extensible attributes in Infoblox using pyinfoblox:

$ python
Python 2.7.3 (default, Mar 13 2014, 11:03:55) 
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyinfoblox import InfobloxWAPI
>>> infoblox = InfobloxWAPI(
...     username='admin',
...     password='p4ssw0rd',
...     wapi='https://infoblox.example.org/wapi/v1.1/'                                                                                                                        
... )
>>> infoblox.fixedaddress.get(network='192.168.1.0/24', _max_results=1) # Get just one fixed address from a specific network
[{u'_ref': u'fixedaddress/ZG5zLmZpeGVkX2FkZHJlc3MkMTAuMjMuMTAuMTg0LjAuLg:192.168.1.184/default', u'ipv4addr': u'192.168.1.184', u'network_view': u'default'}]
>>> infoblox.fixedaddress.get(network='192.168.1.0/24', _max_results=1, _return_fields=['extensible_attributes']) # This would get the extensible attributes only
[{u'_ref': u'fixedaddress/ZG5zLmZpeGVkX2FkZHJlc3MkMTAuMjMuMTAuMTg0LjAuLg:192.168.1.184/default', u'extensible_attributes': {u'my_extensible_attribute': 0}}]
>>> infoblox.fixedaddress.update(objref='fixedaddress/ZG5zLmZpeGVkX2FkZHJlc3MkMTAuMjMuMTAuMTg0LjAuLg:192.168.1.184/default', extensible_attributes={'my_extensible_attribute': 1}) # This would update our extensible attributes
>>> infoblox.fixedaddress.get(network='192.168.1.0/24', _max_results=1, _return_fields=['extensible_attributes']) # Check that we have successfully updated the extensible attributes
[{u'_ref': u'fixedaddress/ZG5zLmZpeGVkX2FkZHJlc3MkMTAuMjMuMTAuMTg0LjAuLg:192.168.1.184/default', u'extensible_attributes': {u'my_extensible_attribute': 1}}]

Please note that in the above example session I'm using Infoblox WAPI version 1.1 where extensible attributes are referred using the extensible_attribute field, while in newer versions you should use extattrs, so you might need to update this for your environment.

Let me know how it goes.

Thanks,
Marin

I'm using the v1.4 API, and the update method is working now, with the new 1.4 extattrs structure

In [1]: from pyinfoblox import InfobloxWAPI, InfobloxWAPIException

In [2]: import json

In [3]: infoblox = InfobloxWAPI(username='admin',
   ...:                         password='p4ssw0rd',
   ...:                         wapi='https://infoblox.example.org/wapi/v1.4/')

In [4]: try:
   ...:     objref = infoblox.fixedaddress.create(name = 'testhost',
   ...:                                           ipv4addr = '192.168.1.184',
   ...:                                           match_client = 'RESERVED')
   ...:     objref = infoblox.fixedaddress.update(objref,
   ...:         extattrs = {
   ...:             'Description': {
   ...:                 'value': 'Set extensible attributes via API'
   ...:             },
   ...:             'Editor': {
   ...:                 'value': 'myself'
   ...:             }
   ...:         })
   ...: except InfobloxWAPIException, e:
   ...:     message = json.loads(e.message)
   ...:     print message['text']
   ...:
In [5]: objref
Out[5]: u'fixedaddress/ZG5zLmZpeGVkX2FkZHJlc3MkMTcyLjI0Ljg3Ljg5LjAuLg:192.168.1.184/default'

In [6]: infoblox.fixedaddress.get(ipv4addr='172.24.87.89', _max_results=1, _return_fields='ipv4addr,name,comment,extattrs')
Out6]: 
[{u'_ref': u'fixedaddress/ZG5zLmZpeGVkX2FkZHJlc3MkMTcyLjI0Ljg3Ljg5LjAuLg:192.168.1.184/default',
  u'extattrs': {u'Description': {u'value': u'Set extensible attributes via API'},
   u'Editor': {u'value': u'philipsd6'}},
  u'ipv4addr': u'192.168.1.184',
  u'name': u'testhost'}]

However, it would be nice if it were possible to do this in the create call, instead of a separate update call, but this still doesn't work (even after I modified the the create() method to use json.dumps(kwargs) as you did in the update() method…)

In [7]: objref = infoblox.fixedaddress.create(name = 'testhost',
   ...:                                       ipv4addr = '192.168.1.184',
   ...:                                       match_client = 'RESERVED',
   ...:                                       extattrs = {
   ...:             'Description': {
   ...:                 'value': 'Set extensible attributes via API'
   ...:             },
   ...:             'Editor': {
   ...:                 'value': 'myself'
   ...:             }
   ...:         })

InfobloxWAPIException: { "Error": "AdmConProtoError: Arguments can not be repeated (extattrs)", 
  "code": "Client.Ibap.Proto", 
  "text": "Arguments can not be repeated (extattrs)"
}

I'm not sure if it's possible to support a that in a single call, but in any case at least I have a good workaround. Thanks!