Introducing SOC Insights for BloxOne Threat Defense: Boost your SOC efficiency with AI-driven insights to eliminate manual work and accelerate investigation and response times. Read the blog announcement here.

API Examples

Reply

Writing WAPI Scripts to Account for Inheritance

[ Edited ]
New Member
Posts: 2
5201     0

I recently helped a customer with a question, and while I was researching it, I noticed there are a few unanswered posts here on the topic. Within NIOS, many settings can be inherited from one or more levels above. If you make a call to get a list of objects with the WAPI, members for example, the fields you are interested in may be blank. For instance, when I make the following WAPI call: 

    

curl -k1 -u admin:infoblox https://10.0.0.23/wapi/v2.6/member?_return_fields=comment,dns_resolver_setting

I get the following result: 

 

[
    {
        "_ref": "member/b25lLnZpcnR1YWxfbm9kZSQw:infoblox.localdomain",
        "dns_resolver_setting": {
            "resolvers": [
                "1.1.1.1"
            ],
            "search_domains": []
        }
    },
    {
        "_ref": "member/b25lLnZpcnR1YWxfbm9kZSQx:rptr.localdomain",
        "dns_resolver_setting": {
            "resolvers": [],
            "search_domains": []
        }
    }
]

Because I set the grid up, I know that one of these members is inheriting from the grid properties, and another member is overriding the default.

 

image.png

 

image.png

 

While using the WAPI there is a feature called Use Flags. A Use Flag is a field that has the same name as another field with "use_" in front of it. These fields are always Boolean values that represent whether the setting is inherited (False) or overridden (True).

 

If we re-run our WAPI call and add the Use Flag for the dns_resolver_setting, we can see which members are inheriting the dns_resolver_setting.

 

curl -k1 -u admin:infoblox https://10.0.0.23/wapi/v2.6/member?_return_fields=comment,dns_resolver_setting,use_dns_resolver_setting

Now we get the following output:

 

[
    {
        "_ref": "member/b25lLnZpcnR1YWxfbm9kZSQw:infoblox.localdomain",
        "dns_resolver_setting": {
            "resolvers": [
                "1.1.1.1"
            ],
            "search_domains": []
        },
        "use_dns_resolver_setting": true
    },
    {
        "_ref": "member/b25lLnZpcnR1YWxfbm9kZSQx:rptr.localdomain",
        "dns_resolver_setting": {
            "resolvers": [],
            "search_domains": []
        },
        "use_dns_resolver_setting": false
    }
]

Notice that for the first member the use_dns_resolver_setting field is "true" while the second member has this value set to "false". This means that the first member is overriding the resolver settings with its own values and the second member is inheriting.

 

OK, great! But, what if we want to know what that value really is since it's not really an empty list in this case? This is where you will have to use some logic in a script or possibly a couple of curl statements.

 

If you just need a quick answer, and you needed to know what the resolvers were for the member above, you know it inherits from the grid, so you could run the following curl command:

 

curl -k1 -u admin:infoblox https://10.0.0.23/wapi/v2.6/grid?_return_fields=dns_resolver_setting

From the output, you will see the resolvers for anything that inherits this setting from the grid:

 

[
    {
        "_ref": "grid/b25lLmNsdXN0ZXIkMA:Infoblox",
        "dns_resolver_setting": {
            "resolvers": [
                "8.8.8.8"
            ],
            "search_domains": []
        }
    }
]

If you wanted to get more elaborate, you could also solve this with a script. While the solution is infinite, I have provided a Python script below that will fetch the object list and replace "interesting" inherited bits with those from the parent. This is just a proof of concept, and it could be made more efficient and handle errors, but it currently is not efficient and does not handle errors.

 

import requests
import json
import pprint

from requests.auth import HTTPBasicAuth
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)


#  Mostly just a POC Script. Probably breaks and doesn't have any error checking.

# INSTRUCTIONS
# Modify the variables below to grab properties on an object. If you want to make
# sure fields with inheritance have actual values, you will need to fill in the USE_FLAGS that you care about

#USER SETTINGS (Modify for your environment)
GM = "10.0.0.23"
WAPI_VERSION= "2.6"
user="admin"
password="infoblox"

#Modify For Request
OBJECT = "member"
RETURN_FIELDS = "comment,dns_resolver_setting,email_setting"
#enter use flags and parent object here. This will be used to "fill in" inheritance gaps
USE_FLAGS = "use_email_setting,use_dns_resolver_setting"
PARENT = "grid"

#END OF USER SETTINGS



url="https://"+GM+"/wapi/v"+WAPI_VERSION+"/"+OBJECT+"?_return_fields=" + RETURN_FIELDS + "," + USE_FLAGS
response = requests.get(url,auth=HTTPBasicAuth(user,password), verify=False)
object_dict = json.loads(response.text)


print USE_FLAGS.replace("use_","") + ": before inheritance fix\n"
for ib_object in object_dict:
    print "\n-------\n_ref: " + ib_object['_ref']
    for key,value in ib_object.items():
        if ("use_" + key) in USE_FLAGS.split(','):
            print key + " -> " + json.dumps(value)
        if (key) in USE_FLAGS.split(','):
            print key + " -> " + json.dumps(value)
    print "\n-----------\n"

for index,ib_object in enumerate(object_dict):
    for key,value in ib_object.items():
        if key in USE_FLAGS.split(',') and value == False:
            INHER_RETURN_FIELD = key.replace("use_","")
            inher_url = "https://"+GM+"/wapi/v"+WAPI_VERSION+"/"+PARENT+"?_return_fields=" + INHER_RETURN_FIELD
            inher_response =  requests.get(inher_url,auth=HTTPBasicAuth(user,password), verify=False)
            inher_dict = json.loads(inher_response.text)[0]
            object_dict[index][INHER_RETURN_FIELD] =inher_dict[INHER_RETURN_FIELD]

print USE_FLAGS.replace("use_","") + ": after inheritance fix\n"
for ib_object in object_dict:
    print "\n-------\n_ref: " + ib_object['_ref']
    for key,value in ib_object.items():
        if ("use_" + key) in USE_FLAGS.split(','):
            print key + " -> " + json.dumps(value)
        if (key) in USE_FLAGS.split(','):
            print key + " -> " + json.dumps(value)
    print "\n-----------\n"

 

If you modify the value of the variables in the USER SETTINGS section, you can tailor this to your environment. In my case, I have set my GM, WAPI version, user and password. I have also set the object that I want to fetch, "member" in this case, as well as the parent of that object, "grid" in this case. RETURN_FIELDS holds the value of the fields which I care about and USE_FLAGS are all of the Use Flags for which I want to "fix" inheritance.

 

In the example above, I am interested in two settings, dns_resolver_setting and email_setting. I also want to fill in the inheritance gaps for both of these settings, so my USE_FLAGS are use_dns_resolver_setting and use_email_setting. 

 

Once run, this script will make the call for you to pull in the objects with the fields you care about. It stores these in a Python dictionary. After that, it will go through and look for cases where dns_resolver_setting or email_setting are inherited. It will actually fetch the grid (parent) settings for these values and update the initial Python dict so that at the end, your dict includes the actual values of the fields in question.

 

Here is the output. Again, not pretty, not efficient, but maybe you can work from the script above to create something that is.

email_setting,dns_resolver_setting: before inheritance fix


-------
_ref: member/b25lLnZpcnR1YWxfbm9kZSQw:infoblox.localdomain
use_email_setting -> false
dns_resolver_setting -> {"resolvers": ["1.1.1.1"], "search_domains": []}
email_setting -> {"relay_enabled": false, "enabled": false}
use_dns_resolver_setting -> true

-----------


-------
_ref: member/b25lLnZpcnR1YWxfbm9kZSQx:rptr.localdomain
use_email_setting -> true
dns_resolver_setting -> {"resolvers": [], "search_domains": []}
email_setting -> {"relay_enabled": false, "enabled": true, "address": "tommy@alsonotreal.com"}
use_dns_resolver_setting -> false

-----------

email_setting,dns_resolver_setting: after inheritance fix


-------
_ref: member/b25lLnZpcnR1YWxfbm9kZSQw:infoblox.localdomain
use_email_setting -> false
dns_resolver_setting -> {"resolvers": ["1.1.1.1"], "search_domains": []}
email_setting -> {"relay_enabled": false, "enabled": true, "address": "test@notarealdomain.com"}
use_dns_resolver_setting -> true

-----------


-------
_ref: member/b25lLnZpcnR1YWxfbm9kZSQx:rptr.localdomain
use_email_setting -> true
dns_resolver_setting -> {"resolvers": ["8.8.8.8"], "search_domains": []}
email_setting -> {"relay_enabled": false, "enabled": true, "address": "tommy@alsonotreal.com"}
use_dns_resolver_setting -> false

-----------

Feel free to take the script and modify as you need to. Re-post a better one if you want. I just hope this gives someone looking to solve this issue an idea from which they can build.

 

If you would like to read more about Use Flags, you can search the WAPI documentation for "Use Flags".

 

Showing results for 
Search instead for 
Did you mean: 

Recommended for You