Learn F5 Technologies, Get Answers & Share Community Solutions Join DevCentral

Filter by:
  • Solution
  • Technology
Answers

Searching and Filtering Objects by Metadata

I've been adding some metadata to the WIPs in our f5 GTMs, eg

"metadata": [ { "name": "xxAppName", "persist": "true", "value": "Web Service" }, { "name": "xxAppOwner", "persist": "true", "value": "myGroup2" }, { "name": "xxAppSupport", "persist": "true", "value": "support_email@mydomain.com" }, { "name": "xxServiceName", "persist": "true", "value": "myService2" }, { "name": "xxWIPStatus", "persist": "true", "value": "active" } ],

This is useful when I'm using Splunk or jq to parse the results, but what if I want to limit the scope of the returned data in the original request, analogous to a filter like "where xxAppSupport == support_email@mydomain.com?" Do any versions of iControl REST (and by extension, the SDK) support this? It'll be really useful when this effort extends to our LTMs. Thanks.

0
Rate this Question

Answers to this Question

placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

I am not familiar with the GTM data structure, but generally speaking, you need to come up with a programmatic solution to selectively obtain the element inside the array (from your example, the value of metadata is an array of dict elements).

Allow me to talk about LTM's datagroup because it has a similar data structure to metadata. Assume that I am looking for the datagroup name that has the records (metadata equivalent) containing the name 'age'.

Here's how you get a list of all the datagroup names:

# curl -sku <user>:<pass> https://<host>/mgmt/tm/ltm/data-group/internal?\$select=name \
 | python -m json.tool | grep name\"
            "name": "aol"
            "name": "images"
            "name": "private_net"
            "name": "sys_APM_MS_Office_OFBA_DG"
            "name": "test"

So, there are five datagroups on this box. The list of records in 'test' looks like this:

# curl -sku <user>:<pass> https://<host>/mgmt/tm/ltm/data-group/internal/test?\$select=records
{"records":[{"name":"addKey","data":"addVal"},{"name":"age","data":"100"},{"name":"name","data":"Satoshi"}]}

So the correct answer is "the name 'age' is in the 'test' datagroup and its value is 100". A python code to achieve this goal is below:

from f5.bigip import ManagementRoot
mgmt = ManagementRoot('host', 'user', 'pass')

# Get all the datagroup names
dataGroupAll = mgmt.tm.ltm.data_group.internals.get_collection()
names = [d.name for d in dataGroupAll]
print('List of internal dgs[{}]: {}'.format(len(names), ', '.join(names)))

# Scan all the records in all the datagroups until it finds the matching value in the name field
dataFound = None
dataIn = None
for dgName in names:
    print 'Checking ', dgName
    dg =mgmt.tm.ltm.data_group.internals.internal.load(name=dgName)
    for ddg in dg.records:
        if ddg['name'] == <the name you are after>:
            dataFound = ddg['data']
            dataIn = dgName
            break
    if dataIn != None:
        break

print('key {}, value {} found in {}'.format(<the name you are after>, dataFound, dataIn))

Example output below:

Checking  aol
Checking  images
Checking  private_net
Checking  sys_APM_MS_Office_OFBA_DG
Checking  test
key age, value 100 found in test

I hope you can tailor the code to suit your needs.

See also F5 Python SDK Documentation.

0
Comments on this Answer
Comment made 3 weeks ago by syncretism 77

I've been using jq and/or python to grab this information programmatically for some time. I think it's clear that there's nothing in the API that allows us to filter this information at the server and reduce the volume coming from the server. That's fine with me; I just wanted to rule it out definitively. Thanks!

0
Comment made 3 weeks ago by Satoshi Toyosawa

If you happen to have a large chunk of datagroup data and want to reduce the return data on the BIG-IP side, how about writing a tmsh script and call it via iControl REST? TCL might be a bit tricky though. TMSH Scripting in v10.1 is a good place to start.

1
Comment made 2 weeks ago by syncretism 77

Thanks for this; I'll keep the idea in my pocket.

0
placeholder+image
USER ACCEPTED ANSWER & F5 ACCEPTED ANSWER

You can use $select. See "About query parameters" in iControl REST User Guide Version 13.1 (pp. 28-29).

For example, GET /mgmt/tm/sys/version (equivalent to tmsh show sys version) returns Build, Edition, Product, Title and Version. When you add the query string $select=Edition, the call returns only the Edition field (and its parents). e.g.,

# curl -sku <user>:<pass> https://localhost/mgmt/tm/sys/version?\$select=Edition | python -m json.tool
{
    "entries": {
        "https://localhost/mgmt/tm/sys/version/0": {
            "nestedStats": {
                "entries": {
                    "Edition": {
                        "description": "Point Release 7"
                    }
                }
            }
        }
    }
}

The above is from LTM but it should also work on GTM/DNS.

0
Comments on this Answer
Comment made 4 weeks ago by syncretism 77

Sorry if I wasn't clear - I'm not looking to limit the output to a single field/attribute/key in metadata.

I want to search for a WIP (or VIP, eventually) where the metadata matches a certain string and return only that. I might use "select" in tandem with that, but it's a different thing, closer to "filter" than "select."

0