This is something I’ve decided to share after a couple of days tinkering with the REST API and wanting to automate adding of hosts.
My environment:
99.99% Windows based
My need:
Automate adding of new hosts as they are deployed on the network.
My plan:
Leverage PowerShell
Leverage WSUS
Leverage the OPSView REST API
My Skills:
I am in no way share or form a developer or someone who could tell you what JSON stands for or how it works. Just a plain old SYS Admin.
Prerequisites:
1. Version of OPSView that has the REST API. I’m using the latest Community Edition.
2. An OPSView contact/login that ha the correct permissions/roles to add new hosts and read data.
3. An OPSView top level host group you will use to host your auto added hosts.
4. A host to clone for your template that new hosts will look like.
5. You should already have WSUS
6. You should know how/what WSUS is.
7. You should know how to create custom WSUS packages and deploy them via WSUS. (Custom Update Publisher)
8. If not read up on them and decide if WSUS is something you want to be using in your org going forward and think about implementing it.
9. It’s simply my environment and thus it is what I want to be working with.
The Details:
So in essence what I want to do is a simple process every time a new Windows Server box is brought up on my domain.
1. Install OPSView agent.
2. Deploy custom .ini config file for agent and restart agent.
3. Add host to monitoring server into a predefined group so I know that this is a new server that needs further setup.
Steps 1 and 2 are easily accomplished with custom WSUS packages and rules to make sure the agent is only deployed when it needs to be and I’m not going to go into that at all. It’s pretty straight forward. If you’ve never done it before you should have the hang of Custom Packages within a day of playing around with it (on your test network of course). Those skills can then be used in the future for other Custom Packages.
This is about accessing the REST API through PowerShell which was something new to me.
I ended up with 2 different raw scripts. Many refinements could be made and I’m sure I’ll tweak them but as of right now these work for what I wanted them to do.
Script 1.
opsview-get-host-config.ps1
This script accesses the API to get the config of a host on the server. I use the output of this script to base my template for adding new hosts. I got the return data and then stripped out information like host ID (can’t duplicate that) and then I insert my own host name and IP when creating the new host later on. I inserted that data into the 2nd script.
Why use that as a template instead of building a host string completely dynamically in the script. This way is easier for me. Of course you can make the script more complex and thus more flexible but again this is a starting point for me (and maybe you) not a universal solution.
Script 2.
opsview-add-host.ps1
This script adds a host with the current IPv4 address and machine name it is running on to the placeholder group. Yes it’s that simple. But it works.
So a simple and useful solution for me. It could be more elegant but it does what I need it to. And once you have your prereqs set up you’d only be using script 2 for adding new hosts and since this can be automated via WSUS hosts will add themselves as your regulated patch cycles happen..
The 2 scripts are attached below.
Thanks for reading and for any comments.
##### opsview-get-host-config.ps1
##### Get OPSview Host Config
$urlauth = "http://opsview.host.org/rest/login"
#The host we will use to pull our data from
$urlconfigget = "http://opsview.host.org/rest/config/host/132"
$user="host-add-contact"
$pass="password"
$creds = '{"username":"' + $user + '","password":"' + $pass + '"}'
#Write-Host $creds
###Generate Auth Token
$bytes1 = [System.Text.Encoding]::ASCII.GetBytes($creds)
$web1 = [System.Net.WebRequest]::Create($urlauth)
$web1.Method = "POST"
$web1.ContentLength = $bytes1.Length
$web1.ContentType = "application/json"
$stream1 = $web1.GetRequestStream()
$stream1.Write($bytes1,0,$bytes1.Length)
$stream1.Close()
$reader1 = New-Object System.IO.Streamreader -ArgumentList $web1.GetResponse().GetResponseStream()
$token1 = $reader1.ReadToEnd()
$reader1.Close()
#Parse Token for follwoing sessions
#Write-Host $token1
$token1=$token1.Replace("{`"token`":`"", "")
$token1=$token1.Replace("`"}", "")
#Write-Host $token1
$web2 = [System.Net.WebRequest]::Create($urlconfigget)
$web2.Method = "GET"
$web2.ContentType = "application/json"
$web2.Headers.Add("X-Opsview-Username","$user")
$web2.Headers.Add("X-Opsview-Token",$token1);
$response2 = $web2.getResponse()
$reader2 = New-Object System.IO.Streamreader -ArgumentList $web2.GetResponse().GetResponseStream()
$result2 = $reader2.ReadToEnd()
Write-Host $result2
$reader2.Close()
##### opsview-add-host.ps1
##### Get OPSview Host Config
$urlauth = "http://opsview.host.org/rest/login"
$urlconfig = "http://opsview.host.org/rest/config/host"
$user="host-add-contact"
$pass="password"
$creds = '{"username":"' + $user + '","password":"' + $pass + '"}'
#Write-Host $creds
###Generate Auth Token
$bytes1 = [System.Text.Encoding]::ASCII.GetBytes($creds)
$web1 = [System.Net.WebRequest]::Create($urlauth)
$web1.Method = "POST"
$web1.ContentLength = $bytes1.Length
$web1.ContentType = "application/json"
$stream1 = $web1.GetRequestStream()
$stream1.Write($bytes1,0,$bytes1.Length)
$stream1.Close()
$reader1 = New-Object System.IO.Streamreader -ArgumentList $web1.GetResponse().GetResponseStream()
$token1 = $reader1.ReadToEnd()
$reader1.Close()
#Parse Token for follwoing sessions
$token1=$token1.Replace("{`"token`":`"", "")
$token1=$token1.Replace("`"}", "")
$hostname = $env:COMPUTERNAME
$hostip = ((ipconfig | findstr [0-9].\.)[0]).Split()[-1]
### The host data I use here is tailored to my OPSView setup. USe the other script and this line as a guide to building your own
$hostdata = '{"object":{"hosttemplates":[{"ref":"/rest/config/hosttemplate/42","name":"Connectivity - USA"},{"ref":"/rest/config/hosttemplate/36","name":"Server - All Windows Server Base Checks"}],"snmpv3_privprotocol":null,"flap_detection_enabled":"1","keywords":[],"check_period":{"ref":"/rest/config/timeperiod/1","name":"24x7"},"hostattributes":[],"notification_period":{"ref":"/rest/config/timeperiod/1","name":"24x7"},"notification_options":"d,r,f","tidy_ifdescr_level":"0","name":"' + $hostname +'","rancid_vendor":null,"snmp_community":"","hostgroup":{"ref":"/rest/config/hostgroup/42","name":"ZZZ-New Hosts"},"enable_snmp":"0","monitored_by":{"ref":"/rest/config/monitoringserver/1","name":"Master Monitoring Server"},"alias":"","parents":[],"uncommitted":"1","icon":{"name":"SYMBOL - Server","path":"/images/logos/server_small.png"},"retry_check_interval":"3","ip":"' + $hostip + '","use_mrtg":"0","snmp_max_msg_size":"0","servicechecks":[],"use_rancid":"0","snmp_version":"2c","snmpv3_authpassword":"","nmis_node_type":"router","use_nmis":"0","rancid_connection_type":"ssh","snmpv3_authprotocol":null,"rancid_username":null,"check_command":{"ref":"/rest/config/hostcheckcommand/15","name":"ping"},"rancid_password":null,"check_attempts":"5","check_interval":"15","notification_interval":"0","snmp_port":"161","snmpv3_username":"","snmpv3_privpassword":"","other_addresses":""}}'
$bytes2 = [System.Text.Encoding]::ASCII.GetBytes($hostdata)
$web2 = [System.Net.WebRequest]::Create($urlconfig)
$web2.Method = "POST"
$web2.ContentLength = $bytes2.Length
$web2.ContentType = "application/json"
$web2.Headers.Add("X-Opsview-Username","$user")
$web2.Headers.Add("X-Opsview-Token",$token1);
$stream2 = $web2.GetRequestStream()
$stream2.Write($bytes2,0,$bytes2.Length)
$stream2.Close()
$reader2 = New-Object System.IO.Streamreader -ArgumentList $web2.GetResponse().GetResponseStream()
$output2 = $reader2.ReadToEnd()
$reader2.Close()
Write-Host $output2
1 comments:
Hi Damir. Nice Post! Would you mind sharing it with other Opsview users on: http://labs.opsview.com/
Post a Comment