check-mk check if hostname and/or ip already exist - bash

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"

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

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}

Related

Bash grep file for string and use each as a variable in another commands

In HA configuration I am checking periodically for VIP address on eth0, (lets call it 2.2.2.2). If it is up, then I need to bring up another group of IP address defined for eth0 in /etc/network/interfaces configuration file:
up ip addr add **1.2.3.34** dev $IFACE
up ip addr add **1.2.3.40** dev $IFACE
up ip addr add **1.2.3.48** dev $IFACE
and pass each IP only to another group of commands:
ip a a **1.2.3.34/32** dev eth0
ip a a **1.2.3.40/32** dev eth0
ip a a **1.2.3.48/32** dev eth0
What I've done so far is:
#!/bin/bash
STATUS=$(ip a s eth0 | grep inet | awk '{print $2}' | sed 's/addr://')
if ip a s eth0 | grep inet | awk '{print $2}' | sed 's/addr://' | grep 2.2.2.2/27 ; then
cat /etc/network/interfaces | grep -o "up ip addr add [0-9]*\.[0-9]*\.[0-9]*\.[0-9]*" | grep -o "[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*" > /tmp/ext_ip.txt
Now I need help how to pass each line to another command mentioned above (ip a a 1.2.3...), but have no idea how to do this properly.
Optionally I'd like to revert operation if VIP is not present in the system - in case if primary HA host will go offline.
One way to achieve this would be to parse all IP addresses into an array and use a for loop to assign them to the interface:
#!/bin/bash
IFACE='eth0'
VIP='192.168.0.1'
IFACES_FILE='/etc/network/interfaces'
STATUS=$( ip address show "$IFACE" | grep -o "$VIP" )
if [ ! -z "$STATUS" ]; then
ip_addresses=( $( grep -o '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' "$IFACES_FILE" ) )
for ip in "${ip_addresses[#]}"; do
ip address add "$ip" dev "$IFACE"
done
fi
This is a simplified example. You may want to add more checks, add some logging messages to provide output useful for debugging. Also, depending on your server configuration some commands may not work without sudo.
Thanks Andrii L. I've improved your solution to:
#!/bin/bash
IFACE='eth0'
VIP='2.2.2.2'
IFACES_FILE='/etc/network/interfaces'
STATUS=$( ip address show "$IFACE" | grep -o "$VIP" )
if [ ! -z "$STATUS" ]; then
ip_addresses=( $( grep -o 'up ip addr add [0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' "$IFACES_FILE" | grep -o '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' ) )
for ip in "${ip_addresses[#]}"; do
ip address add "$ip"/32 dev "$IFACE"
done
else
for ip in "${ip_addresses[#]}"; do
ip address del "$ip"/32 dev "$IFACE"
done
fi
otherwise it is trying to add all IPs and broadcasts found in /etc/network/interfaces file.

use tcpkill command from an ip list

I have got an ip list in a file called ips:
ip1
ip2
I want to tcpkill from this list. I cannot do it from tcpkill command options. I need a script which will write :
tcpkill -i eth0 -9 host ip1 or host ip2
the list can grow in time.
the only thing I know is that I will need a loop to read the list:
for IP in $(cat list) ; do
echo "tcpkill -i eth0 -9 host $IP " (for
the first element of the list)
echo "or host $IP" (for the rest of
the list).
So my questions are:
1. what would be the right syntax for this purpose?
2. Is there a completely different way of doing this?
Any idea folks ?!
thank you very much.
This single line command would append the IP list to tcpkill command to form the complete command:
tcpkill -i eth0 -9 host $(cat list | xargs | sed 's/ / or host /g')
You can put this command after echo to see how the command gets formed.
echo tcpkill -i eth0 -9 host $(cat list | xargs | sed 's/ / or host /g')

Waiting for input from script that is running remotely via ssh

There is a script I'm running that I can not install on the remote machine.
clear && printf '\e[3J'
read -p "Please enter device: " pattern
read -p "Enter date: (YYYY-MM-DD): " date
pfix=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 5 | head -n 1)
mkdir /home/user/logCollectRes/"${pfix}"
ssh xxx.xxx.xxx.xxx 'bash -s' < /usr/local/bin/SearchAdvanced.sh ${pattern} ${date} ${pfix}
In that script, I would like to be able to use read.
ls -g *"${pattern}"*
read -p "Select one of these? [y/n] " "found";
I've tried adding the -n on the read as well as the -t -t option on ssh. As you can see the script presents information that is only seen once the script starts, so I can't use the read on local machine.
EDIT: So lets say server B stores syslogs for 5K computers. The file names are given by using the internal IP of the device and the date at the end.
/var/log/remotes/192.168.1.500201505050736.gz
/var/log/remotes/192.168.1.500201505050936.gz
/var/log/remotes/192.168.1.500201505051136.gz
/var/log/remotes/192.168.1.600201505050836.gz
/var/log/remotes/192.168.1.600201505051036.gz
/var/log/remotes/192.168.1.600201505051236.gz
I'd like to be able to select the IP address from the main script, list all the files matching that IP address, and then select which I want to scp to my local machine.
After speaking with some coworkers I found the answer to be running two scripts: The first pulls the ls -g result and directs the answer to a variable on the local machine. I then print that output with the read option of selecting on of the files. The 2nd script will take that answer and scp the file from the remote machine
In the main script
ssh xxx.xxx.xxx.xxx 'bash -s' < /usr/local/bin/SearchAdvanced.sh ${pattern} ${date} > ${result}
then as a follow up
printf "${result}"
read -p "Select file: "

Shell - Command ignoring extra parameters

I've written a shell script that get's my IP address via curl from http://checkip.amazonaws.com
What i'm attempting to do is get a list of all my security groups and add that IP address to each security group via the AWS CLI.
The script I have so far is:
#!/bin/bash
# Get IP Address
IP_ADDR="`curl http://checkip.amazonaws.com`"
IP_ADDR="$IP_ADDR/32"
cat /dev/null > /tmp/ec2.info
tmpFile="/tmp/ec2.info"
ec2Info=`ec2-describe-group --region eu-west-1 > $tmpFile`
sec_groups=`cat $tmpFile | grep GROUP | cut -f4`
echo "You are using IP Address: $IP_ADDR"
echo ""
for security_group in $sec_groups
do
echo ""
echo $security_group
echo ""
ec2-authorize --region eu-west-1 $security_group –p 22 -s $IP_ADDR
done
The script works fine getting the IP address and a list of my security groups. However, I get an issue when the script gets to the ec2-authorize line.
I get an error message:
WARNING: Ignoring extra parameter(s): [ ?p, 22 ]
Required option '-p, --port-range PORT-RANGE' missing (-h for usage)
As you can see from the script i've added the -p parameter specifying the port. It seems to be ignoring everything after the $security_group variable.
Any ideas?
Instead of a minus sign, you typed an en dash (Unicode U+2013). So just replace –p with -p.
I noticed in your answer, you fixed this without realizing it. That's why it worked, not because you put the args into a var.
And this is why there was a question mark in the error message: [ ?p, 22 ]

In a shell script how to validate if a given host name belongs to localhostname family

In a shell script how to validate if a given host name is localhost
for example :-
localhost
127.0.0.1
myhostname.com
::1
all belong to same machine name, Is there any way to identify that a given host name belongs to localhostname family
Usually all local host names are in /etc/hosts file:
grep -c machine_name /etc/hosts
if the machine name is among the localhost the command above returns 1 or greater, otherwise is 0.
for example:
grep -c myhostname.com /etc/hosts
1
grep -c google.com /etc/hosts
0
Not sure if this is exactly you're looking for but I hope it will help.
Beware of partial match, for example if you have 'myhost' in /etc/hosts grep -c host will return 1 as well. In this case you'll need to use regular expressions or parse /etc/hosts file with cut, awk and similar tools. Or use the following command:
grep -c '\bmachine name\b'
To skip the comments use the command below:
grep -v '^#.*' /etc/hosts | grep -c machine_name
so full command is
grep -v '^#.*' /etc/hosts | grep -c '\bmachine_name\b'
You could check
sysctl kernel.hostname
i.e
sysctl kernel.hostname | grep -c "my_hostname"
I use the following to check whether a supplied hostname is the same as localhost:
hostname_ip(){
host "$1" | sed -e 's/.* \([^ ]*[^ .]\)\.*$/\1/'
}
normalize_hostname(){
local normalized="$1"
grep -q "^\(\([0-9]{1,3}\)\.\)\{3\}\([0-9]{1,3}\)$" <<< "$normalized" || normalized="$(hostname_ip "$normalized")"
normalized="$(hostname_ip "$normalized")"
echo "$normalized"
}
myname="$(normalize_hostname "$(hostname)")"
argname="$(normalize_hostname "$1")"
if [[ "$myname" == "$argname" || "$argname" == "localhost" ]]; then
...
First, normalize the supplied parameter into format set by host utility by running it twice. If IP address is supplied -- checked by regex -- run it only once.
Then compare the value to normalized value of hostname utility or to string "localhost".

Resources