Splunk Search

How to query the deployment server to get the serverclasses for a hostname?

a212830
Champion

We have a chef recipe, that people are using and loving. Now, they want the ability to find out their serverclasses on servers without involving us. Unfortunately, I don't see anyway of doing this by hostname, only by clientname, which, by default, is the GUID.

Anyone?

0 Karma

wrangler2x
Motivator

Here is a search that provides a bit more information on all the forwarders and provides the apps and serverClasses side-by-side:

| rest /services/deployment/server/clients  splunk_server=local
| foreach applications.*.restartSplunkd [eval Apps=if(isnotnull('<<FIELD>>'), mvappend(Apps, "<<MATCHSTR>>"), Apps)]
| foreach serverClasses.*.restartSplunkd [eval ServerClasses=if(isnotnull('<<FIELD>>'), mvappend(ServerClasses, "<<MATCHSTR>>"), ServerClasses)]
| eval Forwarder = lower(dns)
| rex field=utsname "(?<os>[^\-]+)\-(?<arch>.+)"
| eval os = case(os == "linux", "Linux", os == "windows", "Windows", arch == "sun4u", "Solaris", arch == "sun4v", "Solaris")
| fields - utsname
| lookup version2build.csv build
| rename dns AS Forwarder, averagePhoneHomeInterval AS PHI
| stats values(Apps) AS Apps, values(ServerClasses) AS ServerClasses count by Forwarder ip os arch version build clientName splunk_server PHI lastPhoneHomeTime
| fieldformat lastPhoneHomeTime=strftime(lastPhoneHomeTime, "%F %T")
| eval missing=now()-lastPhoneHomeTime-PHI | eval missing=if(missing<0, 0, missing)
| eval Missing=case (missing==0, "No", missing==1, "Yes")
| fields - missing
| addtotals count col=t row=f

And here is that search modified to look for one host inside an XML search form like the one above (same search modified for one host lookup and xml-ified (changed <, >, and " to <, >, and ^quot;). It uses $name$ for the host variable -- you can just drop it into the XML Sloshburch showed, above, replacing what is there between and :

| rest /services/deployment/server/clients  splunk_server=local
| foreach applications.*.restartSplunkd [eval Apps=if(isnotnull('<<FIELD>>'), mvappend(Apps, &quot;<<MATCHSTR>>&quot;), Apps)]
| foreach serverClasses.*.restartSplunkd [eval ServerClasses=if(isnotnull('<<FIELD>>'), mvappend(ServerClasses, &quot;<<MATCHSTR>>&quot;), ServerClasses)]
| eval Forwarder = lower(dns)
| search Forwarder = $name$
| rex field=utsname &quot;(?<os>[^\-]+)\-(?<arch>.+)&quot;
| eval os = case(os == &quot;linux&quot;, &quot;Linux&quot;, os == &quot;windows&quot;, &quot;Windows&quot;, arch == &quot;sun4u&quot;, &quot;Solaris&quot;, arch == &quot;sun4v&quot;, &quot;Solaris&quot;)
| fields - utsname
| lookup version2build.csv build
| rename dns AS Forwarder, averagePhoneHomeInterval AS PHI
| stats values(Apps) AS Apps, values(ServerClasses) AS ServerClasses count by Forwarder ip os arch version build clientName splunk_server PHI lastPhoneHomeTime
| fieldformat lastPhoneHomeTime=strftime(lastPhoneHomeTime, &quot;%F %T&quot;)
| eval missing=now()-lastPhoneHomeTime-PHI | eval missing=if(missing<0, 0, missing)
| eval Missing=case (missing==0, &quot;No&quot;, missing==1, &quot;Yes&quot;)
| fields - missing, count

sloshburch
Splunk Employee
Splunk Employee

How about this:

| REST /services/deployment/server/clients 
 | search name="$host$"
 | fields + applications.*.serverclasses
 | rename "applications.*.serverclasses" AS "*"
 | transpose
 | rename column AS app, "row 1" AS serverclass

Then, save it as a search and have the end users run a REST call to a search which runs | savedsearch search_above(cool) where the token (in this case "cool") is the hostname they are interrogating.

But, to be honest, I think this would work best as a dashboard if they are willing to go to a page:

<form>
  <label>Splunk Deployment Audit</label>
  <fieldset submitButton="false" autoRun="true"></fieldset>
  <row>
    <panel>
      <input type="dropdown" token="name" searchWhenChanged="true">
        <label>Select a deployment client:</label>
        <search>
          <query>| REST /services/deployment/server/clients</query>
        </search>
        <fieldForLabel>name</fieldForLabel>
        <fieldForValue>name</fieldForValue>
      </input>
      <table>
        <search>
          <query>| REST /services/deployment/server/clients 
 | search name="$name$"
 | fields + applications.*.serverclasses
 | rename "applications.*.serverclasses" AS "*"
 | transpose
 | rename column AS app, "row 1" AS serverclass</query>
        </search>
      </table>
    </panel>
  </row>
</form>

jasonwagner
Explorer

Of all the searches I've done, this REST search was the only one that worked for me in 9.0.0.  I tweaked it to give me client per server class so that I could export a csv of my environment.  The only caveat is that it won't include any server classes that don't have any clients phoned home, which is a minor issue.  Note: this must be run from Deployment Server (DS).

| rest /services/deployment/server/clients count=0 splunk_server=local  | table hostname serverClasses.*.stateOnClient 
| untable hostname ServerClassNames dummy 
| rex field=ServerClassNames "serverClasses\.(?<ServerClassNames>[^\.]+)\.stateOnClient$" 
| stats values(hostname) as hostname dc(hostname) by ServerClassNames 
| rename hostname as clientName
| table ServerClassNames, clientName

 

0 Karma

bandit
Motivator

since I was running on a deployment server which is not a search peer, I had to specify splunk_server=mydeployhostnamehere

i.e.
| REST /services/deployment/server/clients splunk_server=mydeployhostnamehere

0 Karma

woodcock
Esteemed Legend

So this worked for you right? If so, be sure to click Accept to close the question.

0 Karma

sloshburch
Splunk Employee
Splunk Employee

Absolutely - good catch!

0 Karma

woodcock
Esteemed Legend

This search will give you a mapping of hostnames/IPs/GUIDs:

index="_internal" (sourcetype="splunkd_access" root="services" user="-" phonehome) OR ((source=*/metrics.log* OR source=*\\metrics.log*) group=tcpin_connections NOT statusee=TcpInputProcessor)
| rex field=uri "connection_(?<clientipPH>\d+\.\d+\.\d+\.\d+)_(?<portPH>\d+)_(?<hostnamePH>(?:\d+\.\d+\.\d+\.\d+)|(?:[^\s]+\.[A-Za-z]{2,3})|[^_]+)_(?<clientnamePH>[^\s]+)_(?<GUIDPH>[^\s_]+)"

a212830
Champion

Was hoping for a REST call, not a Splunk search.

0 Karma

sloshburch
Splunk Employee
Splunk Employee

To add color: I believe @212830 wants it as a REST call so the folks interfacing with the CHEF recipes can continue to use that interface.

Conversely, they can use a REST call to run a search that provides the answer.

0 Karma

woodcock
Esteemed Legend

My search gives you the GUID, then you can use the REST API.

0 Karma
Get Updates on the Splunk Community!

Registration for Splunk University is Now Open!

Are you ready for an adventure in learning?   Brace yourselves because Splunk University is back, and it's ...

Splunkbase | Splunk Dashboard Examples App for SimpleXML End of Life

The Splunk Dashboard Examples App for SimpleXML will reach end of support on Dec 19, 2024, after which no new ...

Understanding Generative AI Techniques and Their Application in Cybersecurity

Watch On-Demand Artificial intelligence is the talk of the town nowadays, with industries of all kinds ...