After migrating all my rules from Cfengine
to Rudder
, i was still missing something. All my freshly kickstarted nodes weren't by default integrated to Rudder
.
While it was fairly easy on my Cfengine
installation to fetch rules for a new node during the kickstart phase, the fact that Rudder
requires the node to be accepted first, was kind of breaking my server provisioning workflow.
Hopefully Rudder API
provides everything's needed to programatically accept a new node on your Rudder
server.
The following init script is to be used at your node's first boot. It will send its inventory to the server, accept it from the pending nodes list and then fetch and apply the rules.
I consider that you've been able to install rudder-agent
and activate this script from you kickstart install prior to the node's first boot.
rudder-installer
init script:
#!/bin/bash
## BEGIN INIT INFO
# Provides: rudder-installer
# Default-Start: 3 4 5
# Default-Stop: 0 1 2 3 4 6
# Required-Start:
#
## END INIT INFO
# rudder-installer: Configure rudder agent
# chkconfig: 345 70 99
# description: Configure rudder agent
# Source function library.
. /etc/init.d/functions
# Variables
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin
API_TOKEN="<YOUR API TOKEN>"
RUDDER_SRV="<YOUR RUDDER SERVER URL>"
RUDDER_SRV_HOSTNAME="<YOUR RUDDER SERVER HOSTNAME>"
# This will remove the script if configuration ended up correctly
clean() {
echo -n "Removing starting script"
chkconfig --del rudder-installer
rm -f /etc/init.d/rudder-installer &> /dev/null
RETVAL=$?
return $RETVAL
}
# Configuration of agent
start() {
echo "Configuring rudder agent"
# Configure server
echo $RUDDER_SRV_HOSTNAME > /var/rudder/cfengine-community/policy_server.dat
# Now declare host on server
echo " - Sending node inventory to the server - Can take up to 10mn please be patient..."
/opt/rudder/bin/cf-agent -KI -D force_inventory &>> /root/rudder.log
# My inotify script will process the new inventory in far less than 10s, but better safe than sorry
echo " - Actually sleeps 10s as it's the needed time to process inventory"
sleep 10
echo " - Verify that node is now pending on the server"
# Ask server using API
I=0
RESULT=$(curl -k -X GET -H 'Content-Type: application/json' -H "X-API-Token: ${API_TOKEN}" -H "X-API-Version: 2" ${RUDDER_SRV}/rudder/api/nodes/pending 2>> /root/rudder.log | sed 's/,/\n/g' | grep $HOSTNAME -B 2)
RET=$?
# Looping to check if node is in pending list
while [ $RET != 0 ]; do
sleep 1
I=$((${I}+1))
if [ $I -lt 30 ]; then
RESULT=$(curl -k -X GET -H 'Content-Type: application/json' -H "X-API-Token: ${API_TOKEN}" -H "X-API-Version: 2" ${RUDDER_SRV}/rudder/api/nodes/pending 2>> /root/rudder.log | sed 's/,/\n/g' | grep $HOSTNAME -B 2)
RET=$?
else
# We exit if the node is still not in pending list
echo "!! Inventory discovery took too long, something must have fail - Exiting"
sleep 5
exit
fi
done
echo " - Get the node ID from the server"
NODEID=$(echo $RESULT | sed 's/.*id\":\"//;s/\".*//')
RET=$?
echo " - Auto accept node"
echo "Accepting node" >> /root/rudder.log
curl -k -X POST -H "X-API-Version: latest" -H "X-API-Token: ${API_TOKEN}" ${RUDDER_SRV}/rudder/api/nodes/pending/${NODEID} -d "status=accepted" &>> /root/rudder.log
# At least should have :)
echo " - Node has been accepted!"
# Yes 6mn is a safe waiting time on my server which takes ~4mn30 to process new server rules
echo " - Now that the node is accepted wait for 6 mn while Rudder server rebuilds rules"
i=0
# Here's the ugly "Make the user wait" timer
while [ $i -lt 360 ]; do
i=$(($i+1))
sleep 1
if [ $i == 30 ]; then
echo -ne "$i"
elif [ $i == 60 ]; then
echo -ne "$i"
elif [ $i == 90 ]; then
echo -ne "$i"
elif [ $i == 120 ]; then
echo -ne "$i"
elif [ $i == 150 ]; then
echo -ne "$i"
elif [ $i == 180 ]; then
echo -ne "$i"
elif [ $i == 210 ]; then
echo -ne "$i"
elif [ $i == 240 ]; then
echo -ne "$i"
elif [ $i == 270 ]; then
echo -ne "$i"
elif [ $i == 300 ]; then
echo -ne "$i"
elif [ $i == 330 ]; then
echo -ne "$i"
else
echo -ne "."
fi
done
# Ok rules should be generated now let's apply them on the node
# I run two first command twice to ensure everything's good - once should be sufficient
echo -e "\n - Updating rules"
echo "### Ensure UUID is correctly detected by the node ###" >> /root/rudder.log
/opt/rudder/bin/cf-agent -KI &>> /root/rudder.log
/opt/rudder/bin/cf-agent -KI &>> /root/rudder.log
echo "### Update rules ###" >> /root/rudder.log
/opt/rudder/bin/cf-agent -KI -b update &>> /root/rudder.log
/opt/rudder/bin/cf-agent -KI -b update &>> /root/rudder.log
echo "### Now apply them ###" >> /root/rudder.log
/opt/rudder/bin/cf-agent -KI &>> /root/rudder.log
RETVAL=$?
return $RETVAL
}
# Init script parameters stuff
case "$1" in
start)
start && success || failure
[[ $? == 0 ]] && clean && success || failure
echo
;;
*)
echo $"Usage: $0 start"
exit 3
;;
esac
So upon completion, the script will remove itself from the init sequence and your freshly installed node should have all required rules applied. If not, consult /root/rudder.log
for details.
You have to use my inotify script on the server, as if you don't you will encounter the infamous "5mn delay" before your node appears in the Rudder
new nodes pending list which would render this init script completely useless as it would exit without applying any rules.
As usual, don't hesitate to contact me if you have any question.