Getting Data In

Splunk REST API: Issue wtih flattening JSON-formatted results

dominiquevocat
SplunkTrust
SplunkTrust

So I call the Splunk REST API and collect results in JSON format and that is kind of okay.
Then I would like to pass it to splunk.Intersplunk.outputResults()
Intersplunk fails to flatten this kind of complex object, so a workaround would be to just get the subset data["entry"] and one leven nesting gets flattened nicely.
However, there are nested elements in that as well like ACL, links, etc.
The nested elements show up as python object in string representation, which you can not then (as a lazy way out) use spath on...
Has anyone found a good way to do this transformation?

example:

{
  "links": {

  },
  "generator": {
    "build": "debde650d26e",
    "version": "6.4.1"
  },
  "updated": "2017-08-04T15:19:21+02:00",
  "origin": "https://xxx:8089/servicesNS/nobody/-/",
  "entry": [
    {
      "links": {
        "alternate": "/servicesNS/nobody/SplunkUniversalForwarder/"
      },
      "name": "SplunkUniversalForwarder",
      "updated": "2017-08-04T15:19:21+02:00",
      "id": "https://xxx:8089/servicesNS/nobody/SplunkUniversalForwarder/"
    },
    {
      "links": {
        "alternate": "/servicesNS/nobody/alert_logevent/"
      },
      "name": "alert_logevent",
      "updated": "2017-08-04T15:19:21+02:00",
      "id": "https://xxx:8089/servicesNS/nobody/alert_logevent/"
    },
    {
      "links": {
        "alternate": "/servicesNS/nobody/introspection_generator_addon/"
      },
      "name": "introspection_generator_addon",
      "updated": "2017-08-04T15:19:21+02:00",
      "id": "https://xxx:8089/servicesNS/nobody/introspection_generator_addon/"
    }
  ]
}
0 Karma
1 Solution

dominiquevocat
SplunkTrust
SplunkTrust

Seems to be mostly good enough:

        if pagehandle.status_code==200:
            data = json.loads(pagehandle.text)
            if "entry" in data:
                results = data["entry"]
                for row in results:
                    #decorate each list item with fields from the returned data
                    if "origin" in data: row["origin"]=data["origin"]
                    if "generator" in data: 
                        row["version"]=data["generator"]["version"]
                        row["build"]=data["generator"]["build"]
                    if "paging" in data: 
                        row["paging:total"]=data["paging"]["total"]
                        row["paging:offset"]=data["paging"]["offset"]
                        row["paging:perPage"]=data["paging"]["perPage"]

                    #flatten notable data
                    if "acl" in row:
                        for acl in row["acl"]:
                            aclitem = str(acl)
                            row[aclitem] = row["acl"][acl]
                        row.pop("acl", None)
                        #alternatively return it as json                        
                        #row["acl"] = json.dumps(row["acl"])
                        #row["acl"].replace("\"", "'")
                    if "perms" in row:
                        if row["perms"] is not None: # there might be "None" values
                            for perm in row["perms"]:
                                permitem = str(perm)
                                row[permitem] = row["perms"][perm]
                            row.pop("perms", None)
                            #alternatively return it as json                        
                            #row["acl"] = json.dumps(row["acl"])
                            #row["acl"].replace("\"", "'")
                    if "content" in row:
                        for content in row["content"]:
                            contentitem = str(content)
                            row[contentitem] = row["content"][content]
                        row.pop("content", None)
                        #alternatively return it as json
                        #row["content"] = json.dumps(row["content"])
                        #row["content"].replace("\"", "'")
                    if "links" in row:
                        for link in row["links"]:
                            linkitem = str(link)
                            row[linkitem] = row["links"][link]
                        row.pop("links", None)
                        #alternatively return it as json
                        #row["links"] = json.dumps(row["links"])
                        #row["links"].replace("\"", "'")
                splunk.Intersplunk.outputResults(results)
            else:
                splunk.Intersplunk.generateErrorResults("nothing to show")

View solution in original post

0 Karma

dominiquevocat
SplunkTrust
SplunkTrust

Seems to be mostly good enough:

        if pagehandle.status_code==200:
            data = json.loads(pagehandle.text)
            if "entry" in data:
                results = data["entry"]
                for row in results:
                    #decorate each list item with fields from the returned data
                    if "origin" in data: row["origin"]=data["origin"]
                    if "generator" in data: 
                        row["version"]=data["generator"]["version"]
                        row["build"]=data["generator"]["build"]
                    if "paging" in data: 
                        row["paging:total"]=data["paging"]["total"]
                        row["paging:offset"]=data["paging"]["offset"]
                        row["paging:perPage"]=data["paging"]["perPage"]

                    #flatten notable data
                    if "acl" in row:
                        for acl in row["acl"]:
                            aclitem = str(acl)
                            row[aclitem] = row["acl"][acl]
                        row.pop("acl", None)
                        #alternatively return it as json                        
                        #row["acl"] = json.dumps(row["acl"])
                        #row["acl"].replace("\"", "'")
                    if "perms" in row:
                        if row["perms"] is not None: # there might be "None" values
                            for perm in row["perms"]:
                                permitem = str(perm)
                                row[permitem] = row["perms"][perm]
                            row.pop("perms", None)
                            #alternatively return it as json                        
                            #row["acl"] = json.dumps(row["acl"])
                            #row["acl"].replace("\"", "'")
                    if "content" in row:
                        for content in row["content"]:
                            contentitem = str(content)
                            row[contentitem] = row["content"][content]
                        row.pop("content", None)
                        #alternatively return it as json
                        #row["content"] = json.dumps(row["content"])
                        #row["content"].replace("\"", "'")
                    if "links" in row:
                        for link in row["links"]:
                            linkitem = str(link)
                            row[linkitem] = row["links"][link]
                        row.pop("links", None)
                        #alternatively return it as json
                        #row["links"] = json.dumps(row["links"])
                        #row["links"].replace("\"", "'")
                splunk.Intersplunk.outputResults(results)
            else:
                splunk.Intersplunk.generateErrorResults("nothing to show")
0 Karma

jkat54
SplunkTrust
SplunkTrust

In that case just use the Python json library, and iterate through dumping strings into results (example of creating results provided in my comments above).

https://docs.python.org/2/library/json.html

0 Karma

jkat54
SplunkTrust
SplunkTrust

Why are you pulling data from the API in a SPL command?

The results in the pipeline are readily available to you.

Are you taking the results of one search and running another based on them?

0 Karma

dominiquevocat
SplunkTrust
SplunkTrust

for the usecase see https://splunkbase.splunk.com/app/2775/ 🙂

0 Karma

jkat54
SplunkTrust
SplunkTrust
import splunk.Intersplunk

# get the keywords suplied to the curl command
keywords, options = splunk.Intersplunk.getKeywordsAndOptions()

# get the previous search results
results,dummyresults,settings = splunk.Intersplunk.getOrganizedResults()

if len(results) > 0:
  for result in results:
    #result["fieldName"] is the field value in one row of your results
    result["fieldName"]="NEW VALUE"

else:
  #no data in pipe
  row={}
  results=[]
  row["foo"] = "bar"
  row["foo2"] = "bar2"
  results.append(row)

splunk.Intersplunk.outputResults(results)
0 Karma
Get Updates on the Splunk Community!

Unlock Database Monitoring with Splunk Observability Cloud

  In today’s fast-paced digital landscape, even minor database slowdowns can disrupt user experiences and ...

Purpose in Action: How Splunk Is Helping Power an Inclusive Future for All

At Cisco, purpose isn’t a tagline—it’s a commitment. Cisco’s FY25 Purpose Report outlines how the company is ...

[Upcoming Webinar] Demo Day: Transforming IT Operations with Splunk

Join us for a live Demo Day at the Cisco Store on January 21st 10:00am - 11:00am PST In the fast-paced world ...