#!/bin/bash ## author : Dryusdan ## date : 30/09/2019 ## description : A vm deployment ## usage : ./deployvm hypervisor/auto templateID/auto/None os-version vm ram cpu ## Import require config ############################## source utils/config source utils/color source utils/logger ####################################################### if [ $# -eq 0 ] then fatal "No arguments supplied. Usage : ./deployvm.sh hypervisor/auto templateID vm ram cpu" fi if [ -z "${1}" ]; then fatal "Hypervisor is not defined. Usage : ./deployvm.sh hypervisor/auto templateID vm ram cpu" else HYPERVISOR="${1}" fi if [ -z "${2}" ]; then fatal "VM Template ID is not defined. Usage : ./deployvm.sh hypervisor/auto templateID vm ram cpu" else VMTPLID="${2}" fi if [ -z "${3}" ]; then fatal "OS-Version is not defined. Usage : ./deployvm.sh hypervisor/auto templateID vm ram cpu" else OSVERSION="${3}" fi if [ -z "${4}" ]; then fatal "VM name is not defined. Usage : ./deployvm.sh hypervisor/auto templateID vm ram cpu" else VMNAME="${4}" fi if [ -z "${5}" ]; then fatal "RAM (MB) is not defined. Usage : ./deployvm.sh hypervisor/auto templateID vm ram cpu" else RAM="${5}" fi if [ -z "${6}" ]; then fatal "Hypervisor is not defined. Usage : ./deployvm.sh hypervisor/auto templateID vm ram cpu" else CPU="${6}" fi info "Get token for Proxmox" PROXMOX_CREDENTIAL=$(curl -s --insecure -d "username=${PROXMOX_USER}@pam&password=${PROXMOX_PASSWORD}" "${PROXMOX_HOST}/api2/json/access/ticket") PROXMOX_TOKEN=$(echo ${PROXMOX_CREDENTIAL} | jq --raw-output '.data.ticket') PROXMOX_CSRF=$(echo ${PROXMOX_CREDENTIAL} | jq --raw-output '.data.CSRFPreventionToken') if [ ${HYPERVISOR} == "auto" ] then info "Get cluster state" bestmemcluster=99999999999999999999999999999999 bestname="" for node in $(curl -s --insecure -b "PVEAuthCookie=${PROXMOX_TOKEN}" "${PROXMOX_HOST}/api2/json/cluster/resources?type=node" | jq --raw-output ".data[] | @base64") do memory=$(echo ${node} | base64 --decode | jq --raw-output ".mem") name=$(echo ${node} | base64 --decode | jq --raw-output ".node") if [[ "${memory}" < "${bestmemcluster}" ]] then bestmemcluster=${memory} bestname=${name} fi done info "Choosing ${bestname}" HYPERVISOR=${bestname} fi if [ ${VMTPLID} == "auto" ] then info "Get template ID" VMTPLID=$(curl -s --insecure -b "PVEAuthCookie=${PROXMOX_TOKEN}" "${PROXMOX_HOST}/api2/json/nodes/${HYPERVISOR}/qemu" | jq --raw-output '.data[] | select(.name=="template-'${OSVERSION}'") | .vmid') fi info "Get new ID" NEWID=$(curl -s --insecure -b "PVEAuthCookie=${PROXMOX_TOKEN}" "${PROXMOX_HOST}/api2/extjs/cluster/nextid" | jq --raw-output ".data") if [ ${VMTPLID} == "" ] then fatal "No VMTPLID. Maybe OS-VERSION variable is wrong" fi if [ "${VMTPLID}" != "None" ] then info "Clone ${VMTPLID} for new vm ${VMNAME}" UPID=$(curl -s --insecure -H "Content-Type: application/x-www-form-urlencoded" -H "CSRFPreventionToken: ${PROXMOX_CSRF}" -b "PVEAuthCookie=${PROXMOX_TOKEN}" -X POST --data "newid=${NEWID}&format=qcow2&full=1&name=${VMNAME}" "${PROXMOX_HOST}/api2/json/nodes/${HYPERVISOR}/qemu/${VMTPLID}/clone" | jq --raw-output '.data') else info "Create new VM ${VMNAME}" fi while [ true ] do info "Task is runnning" sleep 15 if [ "$(curl -s --insecure -b "PVEAuthCookie=${PROXMOX_TOKEN}" "${PROXMOX_HOST}/api2/json/nodes/${HYPERVISOR}/tasks/${UPID}/status" | jq --raw-output '.data.status')" == "stopped" ] then info "Task ended" break fi done info "Get Netbox data for ${HYPERVISOR}" NETBOX_VMBR0=$(curl -s -X GET -H "Authorization: Token ${NETBOX_TOKEN}" -H "Accept: application/json; indent=4" "${NETBOX_URL}${NETBOX_API_PATH}/ipam/ip-addresses/?device=${HYPERVISOR}&interface=vmbr0") info "Get Gateway" GATEWAY=$(echo ${NETBOX_VMBR0} | jq --raw-output '.results[0].address') info "Get VRF ID" VRF=$(echo ${NETBOX_VMBR0} | jq --raw-output '.results[0].vrf.id') info "Get Prefix ID" PREFIX_ID=$(curl -s -X GET -H "Authorization: Token ${NETBOX_TOKEN}" -H "Accept: application/json; indent=4" "${NETBOX_URL}${NETBOX_API_PATH}/ipam/prefixes/?within_include=${GATEWAY}&vrf_id=${VRF}" | jq --raw-output '.results[0].id') info "Get address" ADDRESS=$(curl -s -X GET -H "Authorization: Token ${NETBOX_TOKEN}" -H "Accept: application/json; indent=4" "${NETBOX_URL}${NETBOX_API_PATH}/ipam/prefixes/${PREFIX_ID}/available-ips/" | jq --raw-output '.[0].address') info "get Gateway" GATEWAY=$(echo ${GATEWAY} | cut -d'/' -f1) info "Encode ${ADDRESS}" ENCODEADDRESS=$(echo ${ADDRESS} | sed "s@/@%2F@g") info "Configure ${VMNAME}" curl -s --insecure -H "Content-Type: application/x-www-form-urlencoded" -H "CSRFPreventionToken: ${PROXMOX_CSRF}" -b "PVEAuthCookie=${PROXMOX_TOKEN}" -X PUT -d "ipconfig0=ip%3D${ENCODEADDRESS}%2Cgw%3D${GATEWAY}" "${PROXMOX_HOST}/api2/json/nodes/${HYPERVISOR}/qemu/${NEWID}/config" &> /dev/null info "Get Netbox cluster ID" CLUSTERID=$(curl -s -X GET -H "Authorization: Token ${NETBOX_TOKEN}" -H "Accept: application/json; indent=4" "${NETBOX_URL}${NETBOX_API_PATH}/dcim/devices/?name=${HYPERVISOR}" | jq --raw-output '.results[0].cluster.id') info "Add vm on Netbox" VMID=$(curl -s -X POST -H "Content-Type: application/json" -H "Authorization: Token ${NETBOX_TOKEN}" --data '{"name": "'${VMNAME}'", "cluster": '${CLUSTERID}', "role": 2, "disk": 20}' "${NETBOX_URL}${NETBOX_API_PATH}/virtualization/virtual-machines/" | jq --raw-output '.id') info "Create interface" INTERFACEID=$(curl -s -X POST -H "Content-Type: application/json" -H "Authorization: Token ${NETBOX_TOKEN}" --data '{"virtual_machine": '${VMID}',"name": "eth0", "mtu": 1500, "enabled": "true"}' "${NETBOX_URL}${NETBOX_API_PATH}/virtualization/interfaces/" | jq --raw-output ".id" ) info "Add ip on netbox for this interface ${INTERFACEID}" curl -s -X POST -H "Content-Type: application/json" -H "Authorization: Token ${NETBOX_TOKEN}" --data '{"address": "'${ADDRESS}'","vrf": '${VRF}', "status": "active", "interface": '${INTERFACEID}'}' "${NETBOX_URL}${NETBOX_API_PATH}/ipam/ip-addresses/" &> /dev/null ${UPGRADERAM} ${VMNAME} ${RAM} ${UPGRADECPU} ${VMNAME} ${CPU} info "Starting ${VMNAME}" curl --insecure -H "Content-Type: application/x-www-form-urlencoded" -H "CSRFPreventionToken: ${PROXMOX_CSRF}" -b "PVEAuthCookie=${PROXMOX_TOKEN}" -X POST "${PROXMOX_HOST}/api2/json/nodes/${HYPERVISOR}/qemu/${NEWID}/status/start" &> /dev/null info "Connect to Zabbix" ZABBIX_AUTH_TOKEN=$(curl -s -X POST -H "Content-Type: application/json-rpc" -d '{"jsonrpc": "2.0","method":"user.login","params":{"user":"'${ZABBIX_USER}'","password":"'${ZABBIX_PASS}'"},"auth": null,"id":0}' ${ZABBIX_API} | jq --raw-output '.result') info "Add HOST" VMIP=$(echo ${ADDRESS} | cut -d'/' -f1) curl -s -X POST -H 'Content-Type: application/json-rpc' -d '{"jsonrpc":"2.0","method":"host.create","params": {"host":"'${VMNAME}'","interfaces": [{"type": 1,"main": 1,"useip": 1,"ip": "'${VMIP}'","dns": "","port": "10050"}],"groups": [{"groupid": "'${ZABBIX_HOSTGROUPID1}'"},{"groupid": "'${ZABBIX_HOSTGROUPID2}'"}],"templates": [{"templateid": "'${ZABBIX_TEMPLATEID}'"}]},"auth":"'${ZABBIX_AUTH_TOKEN}'","id":1}' ${ZABBIX_API} &> /dev/null info "Create host_vars" cp templates/host_vars.tpl ${ANSIBLE_PATH}/host_vars/${VMNAME} sed -i "s//${VMNAME}/g" ${ANSIBLE_PATH}/host_vars/${VMNAME} sed -i "s//${VMIP}/g" ${ANSIBLE_PATH}/host_vars/${VMNAME} sed -i "/^\[linux\]/a ${VMNAME} ansible_host=${VMIP}" ${ANSIBLE_PATH}/hosts sed -i "/^\[ferm\]/a ${VMNAME}" ${ANSIBLE_PATH}/hosts info "Waiting 5 minutes for ${VMNAME} starting" sleep 300 info "Run ansible playbook" cd ${ANSIBLE_PATH} ansible-playbook -i hosts ${POSTINSTALL} --limit=${VMNAME} info "Check if ${VMNAME} is pending" RESULT=$(curl -s -X GET -H 'Content-Type: application/json' -H "X-API-Token: ${RUDDER_API_TOKEN}" -H "X-API-Version: 12" ${RUDDER_SRV}/rudder/api/nodes/pending | jq --raw-output '.data.nodes | length') I=0 while [ "${RESULT}" -le "1" ]; do sleep 1 I=$((${I}+1)) if [ $I -lt 30 ]; then RESULT=$(curl -s -X GET -H 'Content-Type: application/json' -H "X-API-Token: ${RUDDER_API_TOKEN}" -H "X-API-Version: 12" ${RUDDER_SRV}/rudder/api/nodes/pending | jq --raw-output '.data.nodes | length') else fatal " Inventory discovery took too long, something must have fail - Exiting" fi done info "Get the node ID from the server" NODEID=$(curl -s -X GET -H 'Content-Type: application/json' -H "X-API-Token: ${RUDDER_API_TOKEN}" -H "X-API-Version: 12" ${RUDDER_SRV}/rudder/api/nodes/pending | jq --raw-output '.data.nodes[0].id') info "Auto accept node" curl -s -X POST -H "X-API-Version: latest" -H "X-API-Token: ${RUDDER_API_TOKEN}" ${RUDDER_SRV}/rudder/api/nodes/pending/${NODEID} -d "status=accepted" &>> /dev/null