Monday, May 30, 2016

[Zabbix] How to add hosts with curl and bash

This is for Zabbix 3.0:
The script executes as follows: addhost.sh 2.2.2.2 testhostname

 
 #!/bin/bash
 IP=$1  
 HOST_NAME=$2  
 # CONSTANT VARIABLES  
 ERROR='0'  
 ZABBIX_USER='Admin' #Make user with API access and put name here  
 ZABBIX_PASS='password' #Make user with API access and put password here  
 ZABBIX_SERVER='zabbix.server.net' #DNS or IP hostname of our Zabbix Server  
 API='https://zzabbix.server.net/api_jsonrpc.php'  
 HOSTGROUPID=6 #What host group to create the server in  
 TEMPLATEID=10001 #What is the template ID that we want to assign to new Servers?  
 # Authenticate with Zabbix API    
 authenticate() {  
         echo `curl -k -s -H 'Content-Type: application/json-rpc' -d "{\"jsonrpc\": \"2.0\",\"method\":\"user.login\",\"params\":{\"user\":\""${ZABBIX_USER}"\",\"password\":\""${ZABBIX_PASS}"\"},\"auth\": null,\"id\":0}" $API`  
     }   
 AUTH_TOKEN=`echo $(authenticate)|jq -r .result`   
 # Create Host  
 create_host() {  
         echo `curl -k -s -H 'Content-Type: application/json-rpc' -d "{\"jsonrpc\":\"2.0\",\"method\":\"host.create\",\"params\": {\"host\":\"$HOST_NAME\",\"interfaces\": [{\"type\": 1,\"main\": 1,\"useip\": 1,\"ip\": \"$IP\",\"dns\": \"\",\"port\": \"10050\"}],\"groups\": [{\"groupid\": \"$HOSTGROUPID\"}],\"templates\": [{\"templateid\": \"$TEMPLATEID\"}]},\"auth\":\"$AUTH_TOKEN\",\"id\":1}" $API`  
     }  
 output=$(create_host)  
 echo $output | grep -q "hostids"  
 rc=$?  
 if [ $rc -ne 0 ]  
  then  
      echo -e "Error in adding host ${HOST_NAME} at `date`:\n"  
      echo $output | grep -Po '"message":.*?[^\\]",'  
      echo $output | grep -Po '"data":.*?[^\\]"'  
      exit  
 else  
      echo -e "\nHost ${HOST_NAME} added successfully\n"  
      # start zabbix agent  
      #service zabbix-agent start  
      exit  
 fi  

Thursday, May 26, 2016

How to export an LVM Volume via ssh if you have no local disk space

Host A has a 40GB Volume but not additional disk space to save the .img to, so you could later copy it somewhere.

You can do this:
dd if=/dev/volumegroup/volumename bs=64k | gzip -c | ssh root@10.0.0.1 'cat > /whereever/volumename.img.gz'

to uncompress the .img do: zcat volumename.img.gz > volumename.img

Sunday, May 22, 2016

[Tutorial] How to resize (bigger) an LVM volume with an encrypted partition used by a VM

Here the version if your crypt device is sitting in a partition as in:

 xvdb                         202:16  0 550G 0 disk   
 --xvdb1                       202:17  0 550G 0 part   
 --luks-1d3d064f-7e4e-4653-99c1-0ef41f213819 (dm-0) 253:0  0 550G 0 crypt   

On Host
#extend to the FINAL size, if you want to add use +, see lvextend man
lvextend -L200G /dev/VGStorage/lvm-test-storage
On VM
umount /opt
cryptsetup luksHeaderBackup /dev/xvdb1 --header-backup-file /root/luksheader
cryptsetup luksClose luks-2892b120-247f-4e7f-834b-816cfb8baf68
fdisk -u /dev/xvdb
d
n
p
1
First Sector: 2048
Last Sector default
w
cat /proc/partitions, confirm number of blocks in partition as given by fdisk
cryptsetup luksOpen /dev/xvdb1 luks-2892b120-247f-4e7f-834b-816cfb8baf68
cryptsetup resize luks-2892b120-247f-4e7f-834b-816cfb8baf68
e2fsck -f /dev/mapper/luks-2892b120-247f-4e7f-834b-816cfb8baf68
resize2fs /dev/mapper/luks-2892b120-247f-4e7f-834b-816cfb8baf68

Saturday, May 21, 2016

[Tutorial] How to resize (bigger) an LVM volume with encryption used as disk by a VM

Case:
Xen Host with Volume Group
1 Volume is used as xvdb by a VM and now you want to resize (bigger) the encrypted volume. This example is for ext2/3/4.
You can do this with running VM.
 xvdb                         202:16  0 550G 0 disk     
 --luks-1d3d064f-7e4e-4653-99c1-0ef41f213819 (dm-0) 253:0  0 550G 0 crypt   

On host:
#extending to 200G in total, use + to add, see man
lvextend -L200G /dev/VGStorage/examplevolume

On VM:
#umount first if not done yet
cryptsetup resize $mappeddevicename
e2fsck -f /dev/mapper/$mappeddevicename
resize2fs /dev/mapper/$mappeddevicename

$mappeddevicename is your mapped device name, which can be something like "secure" or if generated "luks-92342-..."

Monday, May 2, 2016

[tutorial] a primer to cdist

cdist is tool for configuration management, similar to puppy and ansible with the big difference that it does not need an agent on the target machine but only password-less ssh access. The whole thing is based on simple shell scripts and thus needs nearly nothing. Only the control server has 1 dependency: python

start here: git clone https://github.com/ungleich/cdist.git

Basically you have a manifest and types as the 2 most important things. The manifest says what to execute where and can be a simple one liner up to a complex file (see sample file).
Types are the "what is there to do" and can be interdependent, e.g. there is a type called __package which installs packages and automatically uses the correct package manager depending on what distro it detects (via an explorer). Now this type can be used in your type if you need to install dependencies you simply run e.g.
for package in nginx php5 mysql
          do __package $package
done
Another important thing is dependencies. If you have to make sure certain steps need to be done before other steps e.g. build-essential needs to be installed before you can compile something, then you have to use "require". Example"
require="__package/build-essential" __postgres_database $user --owner $user
Pay attention to spaces when you use require! Read manual about that

Now a type directory can contain the following files:
  • manifest (optional)
  • singleton (optional)
  • explorer (optional)
  • gencode (optional) 
  • parameter (optional)
Types are stored below cdist/conf/type/. Their name should always be prefixed with two underscores (__) to prevent collisions with other executables in $PATH.
To implement a new type, create the directory cdist/conf/type/__NAME.
For more explanation of each see: http://www.nico.schottelius.org/software/cdist/man/latest/man7/cdist-type.html

Let's do an example:
We want to create a LEMP stack type:
we create new directory __LEMPstack

In the manifest we put:
#!/bin/sh
for package in nginx mysql-server php5-fpm php5-mysql
       __package $package
done
Now let us assume you want to change the nginx default port and have it reloaded. For that we can use the gencode-remote file, which executes after the other things.
We put the following:
echo "sed -i -e 's/80/8080/g' /etc/nginx/sites-enabled/default"
echo "service nginx reload"

Now to execute that whole thing you can simply put "__LEMPstack" in your manifest that is under /manifest/ (name doesn't matter, for a short one I usually just call it init) and run cdist like this: ./cdist config -v 192.128.100.100
Instead of IP you could also set any hostname if its defined in your manifest (see the sample file).
You will end up with an error about missing object_id. If you want to run types without object_id you need to create a "singleton" file in the type directory. Then it will work.

Best way to learn is to take a look at some of the types that cdist comes with.