#!/bin/bash # Setup deployment parameters function hydra_deploy_setup { # Common parameters # Exclude eventual keys and version control files #DEPLOY_DEPENDENCIES="puppet-common ruby-sqlite3 ruby-activerecord ruby-activerecord-deprecated-finders augeas-tools" DEPLOY_DEPENDENCIES="git rsync puppet hiera-eyaml python3" DEPLOY_RSYNC="rsync -CrltDvpq --no-owner --exclude=/ssl --exclude=keys --exclude=site_keys --exclude=config/secrets --delete --rsync-path" RSYNC_PATH="rsync -q" # Ensure keystore existence mkdir -p $HYDRA_FOLDER/puppet/keys # Fix puppet folder permissions chmod 700 $HYDRA_FOLDER/puppet # Ensure facts and logs folder mkdir -p $HYDRA_FOLDER/puppet/{config/facts,logs} if [ "$1" == "remote" ]; then # Deploy in a remote host if [ ! -z "$2" ]; then NODE="$2" FQDN="$(basename `find $HYDRA_FOLDER/puppet/config/node/ -name $NODE'.*' | head -n 1` .yaml)" # Check for config/node name if [ "$FQDN" == ".yaml" ]; then echo "Cannot find config for $NODE." return 1 fi DEPLOY_BASE="/etc" DEPLOY_COMMAND="$HYDRA_CONNECT $FQDN sudo" DEPLOY_OPTS="$HYDRA_FOLDER/puppet/ $FQDN:/etc/puppet/" DEPLOY_DEST="$FQDN:" RSYNC_PATH="sudo rsync -q" REMOTE_ENV="LC_ALL=C" hydra_deploy_set_manifest || return 1 else echo "No folder specified." return 1 fi elif [ "$1" == "folder" ]; then # Deploy in a local folder if [ ! -z "$2" ]; then FOLDER="$2" DEPLOY_BASE="/etc" DEPLOY_COMMAND="$SUDO chroot $FOLDER" DEPLOY_RSYNC="$SUDO $DEPLOY_RSYNC" DEPLOY_OPTS="$HYDRA_FOLDER/puppet/ $FOLDER/etc/puppet/" DEPLOY_DEST="$FOLDER" # Fix hostname if [ -s "$FOLDER/etc/hostname" ]; then FQDN="`cat $FOLDER/etc/hostname`" else echo "no hostname set at $FOLDER/etc/hostname" return 1 fi hydra_deploy_set_manifest || return 1 if [ ! -d "$FOLDER" ]; then echo "folder not found: $FOLDER" return 1 fi else echo "No node specified." return 1 fi else # Deploy on the localhost DEPLOY_BASE="$HYDRA_FOLDER" DEPLOY_COMMAND="$SUDO" DEPLOY_RSYNC="" FQDN="`cat /etc/hostname`" PUPPET_OPTS="--confdir=$HYDRA_FOLDER/puppet --modulepath=$HYDRA_FOLDER/puppet/modules" hydra_deploy_set_manifest $HYDRA_FOLDER || return 1 # Remove old eyaml symlinks if exists if [ -h "$HYDRA_FOLDER/puppet/keys/private_key.pkcs7.pem" ]; then rm -f $HYDRA_FOLDER/puppet/keys/private_key.pkcs7.pem rm -f $HYDRA_FOLDER/puppet/keys/public_key.pkcs7.pem fi # Use eyaml keypair from the current hostname if [ ! -e "$HYDRA_FOLDER/puppet/keys/private_key.pkcs7.pem" ]; then ln -sf $HYDRA_FOLDER/puppet/keys/$FQDN/eyaml/private_key.pkcs7.pem $HYDRA_FOLDER/puppet/keys/private_key.pkcs7.pem ln -sf $HYDRA_FOLDER/puppet/keys/$FQDN/eyaml/public_key.pkcs7.pem $HYDRA_FOLDER/puppet/keys/public_key.pkcs7.pem fi fi # Common parameters DOMAIN="`echo $FQDN | cut -d . -f 2-`" ROLE="`hydra_yaml_param nodo::role $HYDRA_FOLDER/puppet/config/node/$FQDN.yaml`" LOCATION="`hydra_yaml_param nodo::location $HYDRA_FOLDER/puppet/config/node/$FQDN.yaml`" # Puppet command if [ -e "$HYDRA_FOLDER/puppet/bin/deploy" ]; then DEPLOY_PUPPET="$DEPLOY_BASE/puppet/bin/deploy" else DEPLOY_PUPPET="$REMOTE_ENV puppet apply $PUPPET_OPTS $PUPPET_MANIFEST" fi # Deployment command DEPLOY_APPLY="$DEPLOY_COMMAND $DEPLOY_PUPPET" } # Manifest function hydra_deploy_set_manifest { local prefix="$1" if [ -z "$prefix" ]; then prefix="/etc" fi if [ -e "$HYDRA_FOLDER/puppet/manifests/nodes/$FQDN.pp" ]; then PUPPET_MANIFEST="$prefix/puppet/manifests/nodes/$FQDN.pp" elif [ -e "$HYDRA_FOLDER/puppet/manifests/nodes/default.pp" ]; then PUPPET_MANIFEST="$prefix/puppet/manifests/nodes/default.pp" else echo "no manifest found for $FQDN" return 1 fi } # Return a simple parameter from an YAML file function hydra_yaml_param { local param="$1" local file="$2" #grep "^$param: " $file | cut -d ' ' -f 2 | sed -e "s/'//g" -e 's/"//g' #grep "^$param" $file | sed -e "s/^$param//" | cut -d ':' -f 2 | sed -e "s/'//g" -e 's/"//g' -e "s/ //g" #grep "^$param:[^:]" $file | sed -e "s/^$param://" | sed -e "s/'//g" -e 's/"//g' -e "s/ //g" grep "^$param *:[^:]" $file | sed -e "s/^$param *://" | sed -e "s/'//g" -e 's/"//g' -e "s/ //g" } # Create puppet folder structure function hydra_deploy_mkdirs { # Saner defaults $DEPLOY_COMMAND mkdir -p /etc/puppet/keys $DEPLOY_COMMAND chown -R root: /etc/puppet $DEPLOY_COMMAND chmod -R 640 /etc/puppet } # Copy keys function hydra_deploy_copy_keys { local location="$1" if [ -z "$location" ]; then location="remote" fi # Ensure key availability hydra $HYDRA eyaml $FQDN # Test for multi-keys setup if [ -e "$HYDRA_FOLDER/puppet/keys/$FQDN/eyaml/private_key.pkcs7.pem" ]; then hydra_deploy_copy $location \ $HYDRA_FOLDER/puppet/keys/$FQDN/eyaml/private_key.pkcs7.pem \ $DEPLOY_DEST/etc/puppet/keys/private_key.pkcs7.pem \ || return 1 # Then try single-key setup elif [ -e "$HYDRA_FOLDER/puppet/keys/private_key.pkcs7.pem" ]; then hydra_deploy_copy $location \ $HYDRA_FOLDER/puppet/keys/private_key.pkcs7.pem \ $DEPLOY_DEST/etc/puppet/keys/private_key.pkcs7.pem \ || return 1 fi # Test for multi-keys setup if [ -e "$HYDRA_FOLDER/puppet/keys/$FQDN/eyaml/public_key.pkcs7.pem" ]; then hydra_deploy_copy $location \ $HYDRA_FOLDER/puppet/keys/$FQDN/eyaml/public_key.pkcs7.pem \ $DEPLOY_DEST/etc/puppet/keys/public_key.pkcs7.pem \ || return 1 # Then try single-key setup elif [ -e "$HYDRA_FOLDER/puppet/keys/public_key.pkcs7.pem" ]; then hydra_deploy_copy $location \ $HYDRA_FOLDER/puppet/keys/public_key.pkcs7.pem \ $DEPLOY_DEST/etc/puppet/keys/public_key.pkcs7.pem \ || return 1 fi } # Copy config secrets function hydra_deploy_copy_secrets { local location="$1" if [ -z "$location" ]; then location="remote" fi $DEPLOY_COMMAND mkdir -p $FOLDER/etc/puppet/config/secrets/{domain,location,node,role} || return 1 if [ ! -z "$DOMAIN" ] && [ -e "$HYDRA_FOLDER/puppet/config/secrets/domain/$DOMAIN.yaml" ]; then hydra_deploy_copy $location \ $HYDRA_FOLDER/puppet/config/secrets/domain/$DOMAIN.yaml \ $DEPLOY_DEST/etc/puppet/config/secrets/domain/ \ || return 1 fi if [ ! -z "$LOCATION" ] && [ -e "$HYDRA_FOLDER/puppet/config/secrets/location/$LOCATION.yaml" ]; then hydra_deploy_copy $location \ $HYDRA_FOLDER/puppet/config/secrets/location/$LOCATION.yaml \ $DEPLOY_DEST/etc/puppet/config/secrets/location/ \ || return 1 fi if [ ! -z "$ROLE" ] && [ -e "$HYDRA_FOLDER/puppet/config/secrets/role/$ROLE.yaml" ]; then hydra_deploy_copy $location \ $HYDRA_FOLDER/puppet/config/secrets/role/$ROLE.yaml \ $DEPLOY_DEST/etc/puppet/config/secrets/role/ \ || return 1 fi if [ ! -z "$FQDN" ] && [ -e "$HYDRA_FOLDER/puppet/config/secrets/node/$FQDN.yaml" ]; then hydra_deploy_copy $location \ $HYDRA_FOLDER/puppet/config/secrets/node/$FQDN.yaml \ $DEPLOY_DEST/etc/puppet/config/secrets/node/ \ || return 1 fi } # Copy a single file function hydra_deploy_copy { local location="$1" local orig="$2" local dest="$3" if [ "$location" == "folder" ]; then $SUDO mkdir -p $dest $SUDO cp $orig $dest elif [ "$location" == "remote" ]; then $DEPLOY_RSYNC "$RSYNC_PATH" $orig $dest # Check result if [ "$?" != "0" ]; then echo "Error copying data to $FQDN." return 1 fi fi } # Setup custom facts function hydra_deploy_facts_setup { echo "Setting up custom facts..." ROLE="`hydra_yaml_param nodo::role $HYDRA_FOLDER/puppet/config/node/$FQDN.yaml`" LOCATION="`hydra_yaml_param nodo::location $HYDRA_FOLDER/puppet/config/node/$FQDN.yaml`" if [ -z "$ROLE" ]; then ROLE="default" fi if [ -z "$LOCATION" ]; then LOCATION="default" fi if [ "$1" == "local" ]; then $SUDO mkdir -p /etc/facter/facts.d $SUDO echo "role=$ROLE" | $SUDO tee /etc/facter/facts.d/role.txt > /dev/null $SUDO echo "location=$LOCATION" | $SUDO tee /etc/facter/facts.d/location.txt > /dev/null elif [ "$1" == "remote" ]; then local error $HYDRA_CONNECT $FQDN "sudo mkdir -p /etc/facter/facts.d" || error=1 $HYDRA_CONNECT $FQDN "echo role=$ROLE | sudo tee /etc/facter/facts.d/role.txt > /dev/null" || error=1 $HYDRA_CONNECT $FQDN "echo location=$LOCATION | sudo tee /etc/facter/facts.d/location.txt > /dev/null" || error=1 # Check result #if [ "$?" != "0" ]; then if [ "$error" == "1" ]; then echo "Error setting up facts at $FQDN." return 1 fi fi } # Collects facts from a system function hydra_deploy_facts_collect { echo "Collecting facts from system..." if [ "$1" == "local" ]; then $SUDO facter --yaml > $HYDRA_FOLDER/puppet/config/facts/$FQDN.yaml elif [ "$1" == "remote" ]; then $HYDRA_CONNECT $FQDN sudo facter --yaml > $HYDRA_FOLDER/puppet/config/facts/$FQDN.yaml # Check result if [ "$?" != "0" ]; then echo "Error retrieving facts from $FQDN." return 1 fi fi # Remove transient info sed -i -e '/^ *seconds:/d' -e '/^ *hours:/d' -e '/^ *days:/d' -e '/^ *uptime:/d' \ -e '/^ *uptime:/d' -e '/^ *system_uptime:/d' -e '/^ *memoryfree/d' -e '/^ *swapfree_mb:/d' \ -e '/^ *memorysize/d' -e '/^ *swapfree:/d' -e '/^ *seconds:/d' -e '/^ *hours:/d' \ -e '/^ *days:/d' -e '/^ *uptime_/d' -e '/^ *macaddress:/d' \ $HYDRA_FOLDER/puppet/config/facts/$FQDN.yaml }