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!

Webinar Recap | Revolutionizing IT Operations: The Transformative Power of AI and ML ...

The Transformative Power of AI and ML in Enhancing Observability   In the realm of IT operations, the ...

.conf24 | Registration Open!

Hello, hello! I come bearing good news: Registration for .conf24 is now open!   conf is Splunk’s rad annual ...

ICYMI - Check out the latest releases of Splunk Edge Processor

Splunk is pleased to announce the latest enhancements to Splunk Edge Processor.  HEC Receiver authorization ...