0

we got a script that inserts new hosts in check_mk via curl

#!/bin/bash

cat file.conf | while read line
do

    HOSTNAME=$(echo $line | cut -d '|' -f1)
    IP=$(echo $line | cut -d '|' -f2)


curl "http://myserver/mysite/check_mk/webapi.py?action=add_host&_username=automation&_secret=myautomationsecret" -d 'request={"hostname":"'"$HOSTNAME"'","folder":"ansible","attributes":{"ipaddress":"'"$IP"'","site":"mysite","tag_agent":"cmk-agent"}}'
done 

the file "file.conf" is an already processed file from an nmap scan with xmlstarlet, this file does not always have the hostname, therefore the ip address was used as hostname

the file.conf looks like this

192.168.30.1|192.168.30.1|os
_gateway|192.168.30.2|Linux 2.6.18 - 2.6.22
...

so for some hosts the ip address was passed once as hostname and logically as ip. now it is so that an employee enters the correct hostname and deletes the ip from the field hostname

if the above mentioned script is executed again, it will create the host again with the ip as hostname (because no hostname was specified), so now we have the host 2x in check_mk 1x with the manually added hostname and once with the ip as hostname

all other hosts where the hostname was already recognized correctly by nmap from start on were not taken over like it should be

we now need a function that asks for the ip address of the hostname before the script is executed and if it is already there the host should not be created again

with curl you can only get the hosts

curl "http://myserver/mysite/check_mk/webapi.py?action=get_all_hosts&_username=automation&_secret=myautomationsecret"  
TylerH
  • 20,799
  • 66
  • 75
  • 101
  • Unfortunately i don't have any check_mk for checking, but on they official website you can find also "get_host" instead "get_all_host". Then you will be able to get more information about one specific host ( including IP ). check here https://checkmk.com/cms_web_api_references.html If you put in your question output from one example, then we will know what to do next. – DamianK Mar 31 '20 at 17:45
  • if i do it like this: curl "http://myserver/mysite/check_mk/webapi.py?action=get_host&_username=automation&_secret=myautomationsecret" -d 'request={"hostname":"192.168.30.1"}' i get this: {"result": {"attributes": {"tag_agent": "cmk-agent", "ipaddress": "192.168.30.1", "site": "mysite", "meta_data": {"created_at": 1585659776.593514, "created_by": "automation"}}, "hostname": "192.168.30.1", "path": "ansible"}, "result_code": 0} –  Apr 01 '20 at 05:20
  • but can you change this part "request={"hostname":"192.168.30.1"}" to "request={"ipaddress":"192.168.30.1"}" and show the result ? – DamianK Apr 01 '20 at 07:44
  • yes but like this he can only search for the "hostname" that has the ip adress as hostname cause the curl command is action:get_host and u cant chage that to get_ip –  Apr 01 '20 at 08:02
  • got it, I will prepare some example for you using what we have – DamianK Apr 01 '20 at 08:46
  • would be awesome ^^ maybe if you make hostname = ip address and he recognizes that a host with the ip already exists but has a different hostname so he doesn't create the new host again because it already exists? sry for my rly bad english btw haha –  Apr 01 '20 at 08:52

2 Answers2

0

First you will need "jq", so apt-get install jq. ( is for reading json file by bash )

FILE="filename"
getHost="http://myserver/mysite/check_mk/webapi.py?action=get_all_host&_username=automation&_secret=myautomationsecret"

  while IFS='|' read -r host ip description
  do

    checkHost=$( curl -s "$getHost" | 
     jq -r '.result | keys[] as $k | "\(.[$k] | .attributes | select(.ipaddress=="'$ip'") | .ipaddress )"' | uniq )

    if [ "$checkHost" != "$ip" ]
    then
            # here you already know that this ip ( $ip ) not exist in check_mk
            # put your curl command with add_host action here
            echo "Hostname: $ip added to check_mk"
    else
            echo "Hostname: $ip is already exist in check_mk"

    fi


  done <$FILE
DamianK
  • 387
  • 2
  • 6
  • sounds rly good ty but i get this error: jq: error (at :0): Cannot index string with string "attributes" –  Apr 01 '20 at 12:41
  • but i get this echo aswell: " Hostname: is already exist in check_mk " for every host, the problem is that I have removed a host, but it is not set again, which it should do according to the script –  Apr 01 '20 at 12:43
  • regarding your first question is because json looks probably different when he didn't find such hostname in check_mk , to prevent this message you can change "jq -r '.result.attributes.ipaddress'" to "jq -r '.result.attributes.ipaddress' 2>/dev/null". I already change this in my example too. – DamianK Apr 01 '20 at 13:09
  • But I don’t understand your second question. Can you provide more details ? Add some new output in your question. If script say, that "already exist" it mean that curl find hostname with name $ip ( so column ip from your filename ) – DamianK Apr 01 '20 at 13:12
  • i have renamed the hostname of the host with the ip 30.1 in the checkmk interface but the script still create the host with the ip as hostname and as ip :C this is the first line i get after executing the script: {"result": null, "result_code": 0}Hostname: 192.168.30.1 added to check_mk –  Apr 01 '20 at 13:48
  • Yea, we still have a problem if someone change manually hostname in check_mk, cuz like you wrote we can't have a list from check_mk with hostname and ipaddress ( right ? ) to compare it with your fresh nmap list. There is one way, we can resolve hostname before we run curl to get ip address, but it will work only if your dns or local machine ( etc/hosts ) will know they names. – DamianK Apr 01 '20 at 15:10
  • or how about using the get_all_hosts statement from check_mk: curl "http://myserver/mysite/check_mk/webapi.py?action=get_all_hosts&_username=automation&_secret=myautomationsecret" ? this way you would have all the current hostnames from the interface and the ip addresses. with these you could retrieve the file again or? unfortunately the output of this query is very confusing, but you can see the attributes like the ip address Translated with www.DeepL.com/Translator (free version) –  Apr 01 '20 at 15:27
  • Seriously ? you say before that you can get only hostname or I misunderstood you :))) Anyway now we are back to game. But to help I need to see how this output from "get_all_hosts" looks like – DamianK Apr 01 '20 at 15:41
  • no i meant you can only search for get_all_hosts but not for get_all_ips :)) but that was a bit my mistake oh dear ^^ but it is so that under get_all_hosts the output as described above is very confusing but that is probably the lesser problem –  Apr 01 '20 at 16:44
  • . the output should look almost the same as under get_host: {"result": {"attributes": {"tag_agent": "cmk-agent", "ipaddress": "192.168.30.1", "site":"mysite", "meta_data": {"created_at": 1585659776.593514, "created_by": "automation"}}}, "hostname": "192.168.30.1", "path": "ansible"}, only that with get_all_hosts 1. the hostname is placed in front of the attributes aswell and 2. everything is displayed one after the other which makes it very confusing –  Apr 01 '20 at 16:44
  • ok I change code in my answer , I hope it will work cuz is hard without full picture. Now we are checking if current ip from the list presents in json from check_mk response – DamianK Apr 01 '20 at 18:10
  • but can you tell me what the jq statement does exactly? –  Apr 02 '20 at 05:46
  • First of all im glad that i could help and Im glad that you asking :) jq is a tool that lets you read,filter and write JSON in bash, I recommend to read more about this tool, cuz can be useful for any others scripts that you probably will need in the future In your case we read result and looking for specific ip from the previous loop $ip, "select(.ipaddress=="'$ip'")". "uniq" command at the end is to prevent result with more than one same ip ( cuz in your case it's possible ). The last part is for compare match but i think you already know that. Good luck ! – DamianK Apr 02 '20 at 06:52
0

now we have another problem: i have to include the OS directly. this already works with the same add_host so far, i just had to include another attribute

 curl "http://myserver/mysite/check_mk/webapi.py?action=add_host&_username=automation&_secret=myautomationsecret" -d 'request={"hostname":"'"$HOSTNAME"'","folder":"ansible","attributes":{"ipaddress":"'"$IP"'","tag_os": "'"$OS"'","site":"mysite","tag_agent":"cmk-agent"}}'

but it is so that you have to insert OS names manually into the checkmk interface, there is a special tab where you can define them

this was already done with the OS Linux, Windows and LCOS

but now it is so that the nmap scan does not have an os included everywhere, so the file.conf looks like this from time to time:

host1|192.168.30.25|Windows
host2|192.168.30.90|Linux
host3|192.168.30.110|Linux
host4|192.168.30.111|Linux
192.168.30.130|192.168.30.130|
192.168.30.131|192.168.30.131|Android
192.168.30.155|192.168.30.155|Linux
192.168.30.157|192.168.30.157|

you can see that at hosts the os is completely missing or that there is something like android

we now want the hosts that do NOT have linux, windows or lcos to have "empty" as tag_os

but the curl command gives an error for hosts with empty os and does not create them

{"result": "Check_MK exception: Unknown tag ", "result_code": 1}{"result": "Check_MK exception: No such host", "result_code": 1}