Skip to content

Instantly share code, notes, and snippets.

@jhrcz
Last active October 1, 2016 17:08
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jhrcz/8345792 to your computer and use it in GitHub Desktop.
Save jhrcz/8345792 to your computer and use it in GitHub Desktop.
This is a quick hack for generating part of /etc/hosts to be used with dnsmasq to provide vmid specific dns names for vms running on opennebula. vm with id 456 will have dns record 456.vms.mydomain.local pointing to correct IP. in my test environment, used for generating /etc/host (prepending /etc/hosts.template) from cron to feed dnsmasq ;o)

opennebula addon for dynamic per-vm dns names

this tool allows to have delegated dns domain to opennebula with dns names for every vm.

vm dns names with vmid look like 3456.vms.my.domain.int. additionaly, there are dns names based on vm name with truncated suffix with vmid. this has sideefect for vms with the same base name - it allow having round robin ballancing.

currently we use /etc/hosts.dnsmasq to not interferre with system /etc/hosts. using hosts file has some drawbacks, like nonexistent wildcards.

sample usage

# ssh 75.vms.mydomain.int
Last login: Fri Jan 10 02:33:42 2014 from 192.168.1.80
...

configuration

cron

*/10 * * * * /usr/local/sbin/one-gen-hosts-dnsmasq-cron.sh "192.168" ".vms.onedev1.etn"
*/10 * * * * /usr/local/sbin/one-gen-hosts-dnsmasq-synctons.sh "some-dnsmasq-host"

in addition to this cron task, its better to have opennebula hook to have dns records available in the moment vm is created.

important dnsmasq configuration

on both (intermediate dnsmasq and final mgmt host):

no-hosts
addn-hosts=/etc/hosts.dnsmasq

on intermediate dnsmasq

server=/vms.mydomain.int/10.20.30.40
server=/localdomain/192.168.1.1
local=/vms.mydomain.int/
local=/localnet/

public dnsmasq host

required ssh login to oneadmin user with sudo privilege:

oneadmin ALL=(root) NOPASSWD: /etc/init.d/dnsmasq
  • /etc/hosts.dnsmasq should be writable by oneadmin
  • requires ssh access to oneadmin user with ssh key

sudo rule

script is intended to be run as oneadmin to have access

Cmnd_Alias ONE_DNS = /usr/local/sbin/one-gen-hosts-dnsmasq-cron.sh
Cmnd_Alias ONE_DNS_PUSH = /usr/local/sbin/one-gen-hosts-dnsmasq-synctons.sh
#oneadmin ALL=(ALL) NOPASSWD: ONE_MISC, ONE_NET, ONE_LVM, ONE_ISCSI, ONE_OVS, ONE_XEN
oneadmin ALL=(ALL) NOPASSWD: ONE_MISC, ONE_NET, ONE_LVM, ONE_ISCSI, ONE_OVS, ONE_XEN, ONE_DNS, ONE_DNS_PUSH

vm hook

VM_HOOK = [
  name      = "regen-dns",
  on        = "CREATE",
  command   = "/usr/bin/sudo /usr/local/sbin/one-gen-hosts-dnsmasq-cron.sh",
  arguments = "192.168 .vms.mydomain.int" ]
#!/bin/bash
. /etc/profile
(
echo "# autogenerated file, do not edit"
echo
sudo -u oneadmin /usr/local/sbin/one-gen-hosts-records.sh "$@" 2>/dev/null
echo
) > /dev/shm/hosts.dnsmasq
cat /dev/shm/hosts.dnsmasq > /etc/hosts.dnsmasq
grep "#dnsmasq-syntax:" /etc/hosts.dnsmasq | cut -d : -f 2- > /etc/dnsmasq.d/one-with-wildcards.conf
service dnsmasq restart
#!/bin/bash
SERVER=
JOB=
APIUSER=
APITOKEN=
unset http_proxy
curl -v --user $APIUSER:$APITOKEN http://$SERVER/jenkins/job/$JOB/build
#!/bin/bash
. /etc/profile
NS_HOST="${1}"
NS_USER=oneadmin
RAISE_PRIVS="sudo -u root"
scp /etc/hosts.dnsmasq $NS_USER@$NS_HOST:/etc/hosts.dnsmasq
scp /etc/dnsmasq.d/one-with-wildcards.conf $NS_USER@$NS_HOST:/etc/dnsmasq.d/
ssh $NS_USER@$NS_HOST $RAISE_PRIVS /etc/init.d/dnsmasq restart
#!/bin/bash
[ "$DEBUG" = "YES" ] \
&& set -x
# examples:
#
# IP_PREFIX=192.168
# DOMAIN_SUFFIX=".vms.onedev1.local"
# VMNAMES="YES" for generating vmname based hostnames
IP_PREFIX="$1"
DOMAIN_SUFFIX="$2"
VMNAMES=${VMNAMES:-NO}
onevm list --xml \
| xmlstarlet sel -t -m '/VM_POOL/VM' -v 'ID' -n \
| egrep '^[[:digit:]]' \
| while read id
do
ip=$(
onevm show --xml $id \
| xmlstarlet sel -t -m '/VM/TEMPLATE/NIC' -v IP -n \
| head -n 1
)
templateid=$(
onevm show --xml $id \
| xmlstarlet sel -t -m '/VM/TEMPLATE' -v TEMPLATE_ID -n \
| head -n 1
)
name=$(
onetemplate show --xml $templateid \
| xmlstarlet sel -t -m '/VMTEMPLATE' -v NAME -n \
| sed -e "s,[^a..zA..Z01..9]\[.*$,,g" -e "s,^[^:]*:,,g" \
| head -n 1
)
name_tplhostname=$(
onevm show --xml $id \
| xmlstarlet sel -t -m '/VM/TEMPLATE/CONTEXT' -v HOSTNAME -n \
| sed -e "s,-${id}$,," \
| head -n 1
)
if [ -z "$ip" ]
then
mac=$(
onevm show --xml $id \
| xmlstarlet sel -t -m '/VM/TEMPLATE/NIC' -v MAC -n \
| head -n 1
)
# 02:01:b2:ee:22:9c
m1=$(echo $mac | cut -d ":" -f 5)
m2=$(echo $mac | cut -d ":" -f 6)
ip="${IP_PREFIX}.$(( 0x$m1 )).$(( 0x$m2 ))"
fi
[ -n "$id" ] \
|| continue
[ -n "$id" ] \
&& echo "" \
&& echo "# vmid: ${id}" \
&& echo "#dnsmasq-syntax:address=/${id}${DOMAIN_SUFFIX}/${ip}" \
&& echo "#dnsmasq-syntax:address=/.${id}${DOMAIN_SUFFIX}/${ip}" \
&& echo "${ip} ${id}${DOMAIN_SUFFIX}"
if [ "$VMNAMES" = "YES" ]
then
edname="$(echo "${name}" | sed -E 's/[^-_[:alnum:]]/_/g' )"
[ -n "$edname" ] \
&& echo "#dnsmasq-syntax:txt-record=${edname}.byname${DOMAIN_SUFFIX},vmid=${id}" \
#[ -n "$edname" ] \
# && echo "${ip} ${edname}${DOMAIN_SUFFIX}"
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment