All Apps and Add-ons

Redirector towards multiple url from a table

chizops
Path Finder

This is another question from http://splunk-base.splunk.com/answers/62535/possibility-of-adding-mutiple-url-to-a-redirector-and-se....

I'm able to get a field other than the first cell of the row to be redirected to the appropriate url (view). But now I'm stuck trying to figure out how and where to place the if function in eval. Here is what I have as my redirector so far:


$click.fields.source_address$
$click.fields.destination_address$
$click.fields.severity$
$click.fields.destination_port$
True
$click.fields.source_port$
$user.rawValue$
$search.timeRange.earliest$
$search.timeRange.latest$
port_investigation_drilldown

Where would I put the eval if command? (I'm guessing after url) How would the command string go? Would it be like this: eval port_investigation_drilldown=if($click.fields.source_port$), if($click.fields.destination_port$) | eval ip_investigation_drilldown_Source=if($click.fields.source_address$) and so on.

1 Solution

sideview
SplunkTrust
SplunkTrust

Well I'm not sure of the specifics of your fields and values, but I can certainly illustrate it a bit more.

let's restate the goal -- you want to end up with your table rows having a field called 'url', where the url on each row is appropriate to that row. From your linked question from before, we can say that some rows are 'ports' as defined by having a "source_port" or "dest_port" field, and some rows are 'ips', as defined by having a "source_address" or "dest_address" field.

We'll use the Table module to hold the url values for each row, but it wont actually display the url's visually, courtesy of the Table module's "hiddenFields" param.

Also lets say the view you wanted to redirect ports to was a Splunk view called port_detail, and the view you wanted to redirect addresses to was called ip_detail.

Now, in simple cases you can just nest if statements in eval but since we have to check 4 fields here it would get a big ugly so lets use the case function instead.

eval url=case(isnotnull(source_port) OR isnotnull(dest_port),"port_detail",isnotnull(source_address) OR isnotnull(dest_address),"ip_detail"))

and here's the whole config with the Table and the Redirector.

<module name="Search">
  <param name="search">YOUR SEARCH TERMS | eval url=case(isnotnull(source_port) OR isnotnull(dest_port),"port_detail",isnotnull(source_address) OR isnotnull(dest_address),"ip_detail"))</param>
  <module name="Pager">
    <module name="Table">
      <param name="hiddenFields">url</param>
      <module name="Redirector">
        <param name="url">$click.fields.url$</param>
        <param name="arg.sourceIpAddress">$click.fields.source_address$</param>
        <param name="arg.destinationIpAddress">$click.fields.destination_address$</param>
        <param name="arg.severity">$click.fields.severity$</param>
        <param name="arg.dstport">$click.fields.destination_port$</param>
        <param name="arg.autoRun">True</param>
        <param name="arg.srcport">$click.fields.source_port$</param>
        <param name="arg.user">$user.rawValue$</param>
        <param name="arg.earliest">$search.timeRange.earliest$</param>
        <param name="arg.latest">$search.timeRange.latest$</param>
      </module>
    </module>
  </module>
</module>

However I recommend a couple changes. As a best practice, I strongly recommend, when you have a Pulldown or a TextField that is holding a selected value for a field, make the "name" param of that UI module be exactly the same as the fieldName. For example here you have UI tokens (and presumably thus Pulldowns and TextFields) like "srcport", which map to the field anmes of "source_port". Eliminate this and just have all the UI tokens and name params themselves be "source_port".

The main benefit is simply that you'll have to remember less and it will save a lot of typos. However you'll also be able to use nifty shortcuts like the $name$ keys in TextField in Pulldown, and some fancy auto-drilldown behavior in the Redirector. You don't need to know what I'm talking about, because the brainspace benefits along make it a good best practice.

UPDATE::

I think I understand now -- all rows have ports and ip addresses, and you want to set "drilldown" to "cell" on the SimpleResultsTable, which lets the user pick both the row and the column. then depending on which cell they click, they go to the correct detail view. Here's a way to do that.

<module name="SimpleResultsTable">
  <param name="drilldown">cell</param>

  <module name="PostProcess">
    <param name="search">eval relevant_url=case("$click.name2$"=="source_port" OR "$click.name2$"=="dest_port","port_detail","$click.name2$"=="source_address" OR "$click.name2$"=="dest_address","ip_detail",True,"some_fallback_url") | eval relevant_port=case("$click.name2$"=="source_port",source_port,"$click.name2$"=="dest_port",dest_port) | eval relevant_ip=case("$click.name2$"=="source_address",source_address,"$click.name2$"=="dest_address",dest_address)</param>

    <module name="ResultsValueSetter">
      <param name="fields">relevant_url,relevant_port,relevant_ip</param>

      <module name="Redirector">
        <param name="url">$relevant_url$</param>
        <param name="arg.port">$relevant_port$</param>
        <param name="arg.ip">$relevant_ip$</param>
        <param name="arg.autoRun">True</param>
        <param name="arg.earliest">$search.timeRange.earliest$</param>
        <param name="arg.latest">$search.timeRange.latest$</param>
      </module>
    </module>
  </module>
</module>

It's a bit different. Rather than in my earlier answer where we stashed some hiddenFields for ourselves for later, here we actually let the user click the cell and then with the clicked value in hand we use PostProcess and ResultsValueSetter to determine the correct URL. From splunkd's perspective it's extremely strange - we're asking it whether the literal string "dest_port" is equal to the literal string "dest_port" (Fortunately splunkd does not question our sanity for asking the question).

I hope you get the idea though. To be perfectly honest if I had to do this myself and I was the only one maintaining it, I would probably use a CustomBehavior to do it in javascript. In such a picture you would have a CustomBehavior nested inside the SimpleResultsTable or Table, then a Redirector nested inside the CustomBehavior. The JS would implement getModifiedContext(), basically make the same determination we're making here and set those three different keys and values into the context depending on the $click.name2$ value. If you're comfortable with Javascript I can show you how that works too...

View solution in original post

sideview
SplunkTrust
SplunkTrust

Well I'm not sure of the specifics of your fields and values, but I can certainly illustrate it a bit more.

let's restate the goal -- you want to end up with your table rows having a field called 'url', where the url on each row is appropriate to that row. From your linked question from before, we can say that some rows are 'ports' as defined by having a "source_port" or "dest_port" field, and some rows are 'ips', as defined by having a "source_address" or "dest_address" field.

We'll use the Table module to hold the url values for each row, but it wont actually display the url's visually, courtesy of the Table module's "hiddenFields" param.

Also lets say the view you wanted to redirect ports to was a Splunk view called port_detail, and the view you wanted to redirect addresses to was called ip_detail.

Now, in simple cases you can just nest if statements in eval but since we have to check 4 fields here it would get a big ugly so lets use the case function instead.

eval url=case(isnotnull(source_port) OR isnotnull(dest_port),"port_detail",isnotnull(source_address) OR isnotnull(dest_address),"ip_detail"))

and here's the whole config with the Table and the Redirector.

<module name="Search">
  <param name="search">YOUR SEARCH TERMS | eval url=case(isnotnull(source_port) OR isnotnull(dest_port),"port_detail",isnotnull(source_address) OR isnotnull(dest_address),"ip_detail"))</param>
  <module name="Pager">
    <module name="Table">
      <param name="hiddenFields">url</param>
      <module name="Redirector">
        <param name="url">$click.fields.url$</param>
        <param name="arg.sourceIpAddress">$click.fields.source_address$</param>
        <param name="arg.destinationIpAddress">$click.fields.destination_address$</param>
        <param name="arg.severity">$click.fields.severity$</param>
        <param name="arg.dstport">$click.fields.destination_port$</param>
        <param name="arg.autoRun">True</param>
        <param name="arg.srcport">$click.fields.source_port$</param>
        <param name="arg.user">$user.rawValue$</param>
        <param name="arg.earliest">$search.timeRange.earliest$</param>
        <param name="arg.latest">$search.timeRange.latest$</param>
      </module>
    </module>
  </module>
</module>

However I recommend a couple changes. As a best practice, I strongly recommend, when you have a Pulldown or a TextField that is holding a selected value for a field, make the "name" param of that UI module be exactly the same as the fieldName. For example here you have UI tokens (and presumably thus Pulldowns and TextFields) like "srcport", which map to the field anmes of "source_port". Eliminate this and just have all the UI tokens and name params themselves be "source_port".

The main benefit is simply that you'll have to remember less and it will save a lot of typos. However you'll also be able to use nifty shortcuts like the $name$ keys in TextField in Pulldown, and some fancy auto-drilldown behavior in the Redirector. You don't need to know what I'm talking about, because the brainspace benefits along make it a good best practice.

UPDATE::

I think I understand now -- all rows have ports and ip addresses, and you want to set "drilldown" to "cell" on the SimpleResultsTable, which lets the user pick both the row and the column. then depending on which cell they click, they go to the correct detail view. Here's a way to do that.

<module name="SimpleResultsTable">
  <param name="drilldown">cell</param>

  <module name="PostProcess">
    <param name="search">eval relevant_url=case("$click.name2$"=="source_port" OR "$click.name2$"=="dest_port","port_detail","$click.name2$"=="source_address" OR "$click.name2$"=="dest_address","ip_detail",True,"some_fallback_url") | eval relevant_port=case("$click.name2$"=="source_port",source_port,"$click.name2$"=="dest_port",dest_port) | eval relevant_ip=case("$click.name2$"=="source_address",source_address,"$click.name2$"=="dest_address",dest_address)</param>

    <module name="ResultsValueSetter">
      <param name="fields">relevant_url,relevant_port,relevant_ip</param>

      <module name="Redirector">
        <param name="url">$relevant_url$</param>
        <param name="arg.port">$relevant_port$</param>
        <param name="arg.ip">$relevant_ip$</param>
        <param name="arg.autoRun">True</param>
        <param name="arg.earliest">$search.timeRange.earliest$</param>
        <param name="arg.latest">$search.timeRange.latest$</param>
      </module>
    </module>
  </module>
</module>

It's a bit different. Rather than in my earlier answer where we stashed some hiddenFields for ourselves for later, here we actually let the user click the cell and then with the clicked value in hand we use PostProcess and ResultsValueSetter to determine the correct URL. From splunkd's perspective it's extremely strange - we're asking it whether the literal string "dest_port" is equal to the literal string "dest_port" (Fortunately splunkd does not question our sanity for asking the question).

I hope you get the idea though. To be perfectly honest if I had to do this myself and I was the only one maintaining it, I would probably use a CustomBehavior to do it in javascript. In such a picture you would have a CustomBehavior nested inside the SimpleResultsTable or Table, then a Redirector nested inside the CustomBehavior. The JS would implement getModifiedContext(), basically make the same determination we're making here and set those three different keys and values into the context depending on the $click.name2$ value. If you're comfortable with Javascript I can show you how that works too...

chizops
Path Finder

So after a lot of trial and error I got it to work, basically it was the quotations that were messing everything up. Thanks for your help!!

0 Karma

sideview
SplunkTrust
SplunkTrust

And downstream from the PostProcess you have the ResultsValueSetter, and downstream from RVS you have the Redirector? And you have the arg.port and arg.ip params set on the Redirector? Can you put your current XML on pastebin?

0 Karma

chizops
Path Finder

Sorry, I've done that already, switched from click to row. It's the same result

0 Karma

sideview
SplunkTrust
SplunkTrust

Note my comment just above, saying that if you're using the Table module, the prefixes are all "row.", so you want $row.name2$, not $click.name2$. Also see my advice above about using the HTML module to debug, and commenting out the Redirector while you're debugging.

0 Karma

chizops
Path Finder

Sorry what I mean by value not set is that the value is not carried over.

0 Karma

chizops
Path Finder

So I've tried this with Table module and it still does not work. It may have something to do with the search command. I've tried only sticking with ports to keep it simple so my PostProcess search is relevant_port=case("$click.name2$"="source_port",source_port,"$click.name2$"="destination_port",destination_port) and the ResultsValueSetter field is relevant_port. As you can see I took 1 of the = out although I tired it with the whole string (copy and paste). So far it brings me to the other view (the port detail view) but the value is not set.

0 Karma

chizops
Path Finder

Ok, I'll try that

0 Karma

sideview
SplunkTrust
SplunkTrust

One more point - with SimpleResultsTable, with default settings the keys all begin with "click", ie "click.value" and "click.fields.someFieldName". However if you're using the Sideview Table module (as you should), the default prefix is "row", so "row.fields.someFieldName". If you want to change it, you set the "drilldownPrefix" param, but fyi the default with Table is "row" instead of "click".

0 Karma

chizops
Path Finder

Ok, our admin installed the latest just now

0 Karma

sideview
SplunkTrust
SplunkTrust

In general there are some big improvements and additions in 2.2.X over 2.1.X, but in this case with these configs no it's not significant. One general piece of advice is to use the HTML module as a cheap debugger. throw an HTML module downstream from the ResultsValueSetter, temporarily comment out the Redirector, and this will allow you to debug the keys that are there. You can also debug the search and postprocess strings with $search$ and $postProcess$ respectively, and then cross-check whether the postProcess search works by running it in the search UI in another window.

0 Karma

chizops
Path Finder

crap, there's 2.2.2 now, I'm on 2.1.2. Oh to the fields being plural. Big difference between 2.1.2 and 2.2.2?

0 Karma

sideview
SplunkTrust
SplunkTrust

(note that it's $click.fields.fieldname$ - fields is plural) Are you using the latest Sideview Utils from the sideview site (2.2.2) or the much older version that's on Splunkbase (1.3.6)?

0 Karma

chizops
Path Finder

So far I have not been able to get this to work.
Coppied as is, does not work (nothing happens) edited the fields. Nothing. If I'm supposed to edit anything can you point it out? I even tried using $click.field.fieldname$ (click.field.source_address) and that does not work.

0 Karma

chizops
Path Finder

Haha, javascript huh? I'm just getting started with xml. I have no programming background except for maybe some html from a long long time ago in a galaxy far far away. This was a dashboard with views from side utils 1 and I'm updating it to do what my supervisor needs it to do. I try and set this for now but I do plan on creating a new dashboard using the up-to-date method.

0 Karma

sideview
SplunkTrust
SplunkTrust

oh I see. So you have "drilldown" set to "cell" rather than "row". I rarely see that anymore. Sorry about that. Let me update my answer.

0 Karma

chizops
Path Finder

That's what I was trying to say. Each row has several fields. For instance all rows have fields Source IP, Dest IP, Source Port, Dest Port, etc. I want to be able to click on the value of either of those fields and it brings me to the proper view for more details. So in other words 1 row does not go to a url but the field itself. In other words, yes, the clickable field is one of many values.

0 Karma

sideview
SplunkTrust
SplunkTrust

Well, I think that's what I assumed, but maybe I'm missing something. Bottom line - what precisely determines whether each row should map to a port_detail or a ip_detail url? I assumed it was the presence/absence of the relevant fields and I write the example that way. If instead it's a field value being one of two values you have to write it differently.

0 Karma

chizops
Path Finder

Actually the source IP, dest IP, ports and such are all on the same row. The idea is to pick the a value in either field of the row and then get redirected to the proper view. Would the eval string still work? My search term looks like this:

threat_content_name="$threat$" | table _time, threat_content_name, source_address, source_country, source_port, destination_address, destination_country, destination_port, action, actionflags, application, category, eventcount, hostinbound_interface, ip_protocol, linecount, log_action, outbound_interface, repeat_count, rule, seqno, serial_no

0 Karma
Get Updates on the Splunk Community!

Index This | I am a number, but when you add ‘G’ to me, I go away. What number am I?

March 2024 Edition Hayyy Splunk Education Enthusiasts and the Eternally Curious!  We’re back with another ...

What’s New in Splunk App for PCI Compliance 5.3.1?

The Splunk App for PCI Compliance allows customers to extend the power of their existing Splunk solution with ...

Extending Observability Content to Splunk Cloud

Register to join us !   In this Extending Observability Content to Splunk Cloud Tech Talk, you'll see how to ...