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!

Introducing the 2024 SplunkTrust!

Hello, Splunk Community! We are beyond thrilled to announce our newest group of SplunkTrust members!  The ...

Introducing the 2024 Splunk MVPs!

We are excited to announce the 2024 cohort of the Splunk MVP program. Splunk MVPs are passionate members of ...

Splunk Custom Visualizations App End of Life

The Splunk Custom Visualizations apps End of Life for SimpleXML will reach end of support on Dec 21, 2024, ...