** Applies to Statseeker v5.6.1 and earlier **
Index
Overview
The Statseeker Discovery process can be refined to include/exclude devices based on supplied IP ranges, and the contents of a hosts file, supplied to the discovery process. It can be further refined through SNMP filtering using: and iftype rules.
- System description rules - matching a string against the contents of the device's sysDescr field/oid
- Interface type rules - matching against an interface's iftype field/oid
The discovery process references a list of supplied SNMP community strings to communicate with the devices on your network. These community strings, along with the SNMP filtering rules, are applied globally across your network during discovery.
In this article we'll be looking at using the Statseeker API to override these global settings, and employ IP range specific community strings and filtering rules.
For more information on:
- The discovery process, see SNMP Discovery
- SNMP filtering rules, see SNMP Device Filtering
- The Statseeker API, see RESTful API v2.1(latest), API Resource-Level Endpoint Reference, and Working with API Filters
- The API resource endpoint referenced in our example, see discover_config
Update the Existing Discovery Configuration
The following example will update the current discovery configuration to provide additional community strings to select IP ranges:
- Devices in the 10.100.89[10, 30, 250-254] range will be sent the default public string, and the range specific secretCommunity community string, and an exclusion rule for Cisco devices will also be applied to this range
- Devices in the 10.100.90.* range will be sent the default public string, and the range specific verySecretCommunity community string
curl \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer myToken" \
-X PUT \
"https://myStatseekerServer/api/latest/discover_config/1?indent=3&links=none" \
-d '{"data":[{"ip_range_configurations":[{"enabled":"true","includes":[""],"excludes":["Cisco"],"iftype":["ethernetCsmacd"],"communities":["secretCommunity","public"],
"ip_range_text":"include 10.100.89.[10,30,250-254]","title":"10.100.89_nonCisco_discovery"},{"enabled":"true","includes":[""],"excludes":[""],"iftype":["ethernetCsmacd"],"communities":["verySecretCommunity","public"],
"ip_range_text":"include 10.100.90.[0-255]","title":"10.100.90_discovery"}]}]}'
# import requests for handling connection and encoding
import requests
import json
def do_request(server, query, user, pword, reqData):
# Run auth request
headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
url = f'https://{server}/ss-auth'
authData = {'user': user, 'password': pword}
resp = requests.post(url, headers=headers, data=authData, verify=False)
headers['Content-Type'] = 'application/json'
url = f'https://{server}/{query}'
if resp.status_code == 200:
# Authentication successful, Statseeker at least v5.5.4
myToken = resp.json()
headers['Authorization'] = f'Bearer {myToken["access_token"]}'
resp = requests.put(url, headers=headers, verify=False, data=reqData)
if resp.status_code != 200:
# Either Authentication was unsuccessful (Statseeker not v5.5.4 or higher), or API set to use basic auth
# Try basic auth
resp = requests.put(url, headers=headers, auth=(user, pword), verify=False, data=reqData)
return resp
# Statseeker Server IP
server = 'your.statseeker.server'
# credentials
user = 'api_user'
pword = 'user_password'
# API root endpoint
query = 'api/latest'
# specify target endpoint
query += '/discover_config/1'
# optional response formatting
query += '/?indent=3&links=none'
# data
reqData = json.dumps({"data":[{"ip_range_configurations":[{"enabled":"true","includes":[""],"excludes":["Cisco"],"iftype":["ethernetCsmacd"],"communities":["secretCommunity","public"],"ip_range_text":"include 10.100.89.[10,30,250-254]","title":"10.100.89_nonCisco_discovery"},{"enabled":"true","includes":[""],"excludes":[""],"iftype":["ethernetCsmacd"],"communities":["verySecretCommunity","public"],
"ip_range_text":"include 10.100.90.[0-255]","title":"10.100.90_discovery"}]}]})
# Run the request
resp = do_request(server, query, user, pword, reqData)
if resp.status_code == 200:
print(resp.status_code)
print(resp.json())
else:
print(f'Error: {resp.status_code} {resp.reason}')
# install with: $ gem install rest-client
require "rest_client"
require "json"
require "base64"
def try_basic(server, query, user, pword, reqData)
headers = {
:content_type => "application/json"
}
url = "https://" + server + "/" + query
headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
return RestClient::Request.execute(
:method => :put,
:url => url,
:headers => headers,
:verify_ssl => false,
:payload => reqData
)
end
def do_request(server, query, user, pword, reqData)
# Run auth request
headers = {
:content_type => "application/x-www-form-urlencoded"
}
url = "https://" + server + "/ss-auth"
authData = {
:user => user,
:password => pword
}
begin
resp = RestClient::Request.execute(
:method => :post,
:url => url,
:headers => headers,
:verify_ssl => false,
:payload => authData
)
rescue RestClient::Unauthorized
# bad credentials or Statseeker not v5.5.4 or higher
try_basic(server, query, user, pword, reqData)
else
# Authentication successful. Statseeker at least v5.5.4
headers = {
:content_type => "application/json"
}
url = "https://" + server + "/" + query
rdata = JSON.parse(resp)
headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
return RestClient::Request.execute(
:method => :put,
:url => url,
:headers => headers,
:verify_ssl => false,
:payload => reqData
)
end
rescue RestClient::Unauthorized
# Statseeker = v5.5.4 but configured for basic auth
try_basic(server, query, user, pword, reqData)
end
# Statseeker Server IP
$server = 'your.statseeker.server'
# api user credentials
$user = 'api_user'
$pword = 'user_password'
# api root endpoint
$query = 'api/latest'
# specify target endpoint
$query += 'discover_config/1'
# optional response formatting
$query += '/?indent=3&links=none'
# configure payload
$reqData = '{"data":[{"ip_range_configurations":[{"enabled":"true","includes":[""],"excludes":["Cisco"],"iftype":["ethernetCsmacd"],"communities":["secretCommunity","public"],
"ip_range_text":"include 10.100.89.[10,30,250-254]","title":"10.100.89_nonCisco_discovery"},{"enabled":"true","includes":[""],"excludes":[""],"iftype":["ethernetCsmacd"],"communities":["verySecretCommunity","public"],
"ip_range_text":"include 10.100.90.[0-255]","title":"10.100.90_discovery"}]}]}'
# Run the request
resp = do_request($server, $query, $user, $pword, $reqData)
puts "#{resp.to_str}"
{
"version": "2.1",
"revision": "12",
"info": "The Statseeker RESTful API",
"data": {
"success": true,
"errmsg": "ok",
"time": 1654742766
}
}
Review the New Discovery Configuration
The following code is checking the Discovery Configuration to ensure that the changes specified above have been applied.
curl \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer myToken" \
-X GET \
"https://myStatseekerServer/api/latest/discover_config/1?fields=ip_range_configurations&indent=3&links=none"
# import requests for handling connection and encoding
import requests
import json
def do_request(server, query, user, pword):
# Run auth request
headers = { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' }
url = f'https://{server}/ss-auth'
authData = {'user': user, 'password': pword}
resp = requests.post(url, headers=headers, data=authData, verify=False)
headers['Content-Type'] = 'application/json'
url = f'https://{server}/{query}'
if resp.status_code == 200:
# Authentication successful, Statseeker at least v5.5.4
myToken = resp.json()
headers['Authorization'] = f'Bearer {myToken["access_token"]}'
resp = requests.get(url, headers=headers, verify=False)
if resp.status_code != 200:
# Either Authentication was unsuccessful (Statseeker not v5.5.4 or higher), or API set to use basic auth
# Try basic auth
resp = requests.get(url, headers=headers, auth=(user, pword), verify=False)
return resp
# Statseeker Server IP
server = 'your.statseeker.server'
# credentials
user = 'api_user'
pword = 'user_password'
# API root endpoint
query = 'api/v2.1'
# specify target endpoint
query += '/discover_config/1'
# specify fields to be returned
query += '/?fields=ip_range_configurations'
# optional response formatting
query += '&indent=3&links=none'
# Run the request
resp = do_request(server, query, user, pword)
if resp.status_code == 200:
print(resp.status_code)
print(resp.json())
else:
print(f'Error: {resp.status_code} {resp.reason}')
# install with: $ gem install rest-client
require "rest_client"
require "json"
require "base64"
def try_basic(server, query, user, pword)
headers = {
:content_type => "json"
}
url = "https://" + server + "/" + query
headers["Authorization"] = "Basic " + Base64.encode64("#{user}:#{pword}")
return RestClient::Request.execute(
:method => :get,
:url => url,
:headers => headers,
:verify_ssl => false
)
end
def do_request(server, query, user, pword)
# Run auth request
headers = {
:content_type => "application/x-www-form-urlencoded"
}
url = "https://" + server + "/ss-auth"
authData = {
:user => user,
:password => pword
}
begin
resp = RestClient::Request.execute(
:method => :post,
:url => url,
:headers => headers,
:verify_ssl => false,
:payload => authData
)
rescue RestClient::Unauthorized
# bad credentials or Statseeker not v5.5.4 or higher
try_basic(server, query, user, pword)
else
# Authentication successful. Statseeker at least v5.5.4
headers = {
:content_type => "application/json"
}
url = "https://" + server + "/" + query
rdata = JSON.parse(resp)
headers["Authorization"] = "Bearer " + rdata.fetch("access_token")
return RestClient::Request.execute(
:method => :get,
:url => url,
:headers => headers,
:verify_ssl => false,
)
end
rescue RestClient::Unauthorized
# Statseeker = v5.5.4 but configured for basic auth
try_basic(server, query, user, pword)
end
# Statseeker Server IP
$server = 'your.statseeker.server'
# api user credentials
$user = 'api_user'
$pword = 'user_password'
# api root endpoint
$query = 'api/v2.1'
# specify target endpoint
$query += '/discover_config/1'
# specify fields to be returned
$query += '/?fields=ip_range_configurations'
# optional response formatting
$query += '&indent=3&links=none'
# Run the request
resp = do_request($server, $query, $user, $pword)
puts "#{resp.to_str}"
{
"version": "2.1",
"revision": "12",
"info": "The Statseeker RESTful API",
"data": {
"success": true,
"errmsg": "ok",
"time": 1654742149,
"objects": [
{
"type": "discover_config",
"sequence": 1,
"status": {
"success": true,
"errcode": 0
},
"data_total": 1,
"data": [
{
"ip_range_configurations": [
{
"enabled": true,
"title": "10.100.89_nonCisco_discovery",
"ip_range_text": "include 10.100.89.[10,30,250-254]",
"snmpv3_credentials": [],
"communities": [
"secretCommunity",
"public"
],
"includes": [
""
],
"excludes": [
"Cisco"
],
"iftype": [
"ethernetCsmacd"
],
"ip_ranges": [
[
174348554,
174348554
],
[
174348574,
174348574
],
[
174348794,
174348798
]
]
},
{
"enabled": true,
"title": "10.100.90_discovery",
"ip_range_text": "include 10.100.90.[0-255]",
"snmpv3_credentials": [],
"communities": [
"verySecretCommunity",
"public"
],
"includes": [
""
],
"excludes": [
""
],
"iftype": [
"ethernetCsmacd"
],
"ip_ranges": [
[
174348800,
174349055
]
]
}
],
"id": 1
}
]
}
]
}
}