#!/bin/bash # Copyright: 2023 Virtuozzo International GmbH # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. [ -n "${BALLIB_VERSION:-}" ] && return 0; BALLIB_VERSION="0.1"; VERBOSE=0 include log; $PROGRAM 'grep'; $PROGRAM 'sed'; $PROGRAM 'awk'; $PROGRAM 'perl'; NGINX_CONFIG='/etc/nginx/nginx-jelastic.conf'; # main nginx config file NGINX_SSL_CONFIG="/etc/nginx/conf.d/ssl.conf"; DHCPD_CONFIG='/etc/dhcp/dhcpd.conf'; NGINX_TCPMAP_CONFIG='/etc/nginx/tcpmaps/mappings.xml'; NGINX_TCPMAP_TEMPLATE='/etc/nginx/templates/nginx.tcp.conf.tpl'; NGINX_CONFIG_TEMPLATE='/etc/nginx/templates/nginx.conf.tpl' ; # template of nginx configuration NGINX_NOBACKENDS_CONFIG_TEMPLATE='/etc/nginx/templates/nginx.conf.nobackends.tpl'; DHCPD_CONFIG_TEMPLATE='/etc/dhcp/dhcpd.tpl'; UPSTREAMS_LOCATION_PATH='/etc/nginx/upstreams'; # upstream configs location UPSTREAM_COMMON_CONFIG=$UPSTREAMS_LOCATION_PATH/common ; # common upstream hosts FLUSH_LEASES_COMMAND="echo > /var/lib/dhcpd/dhcpd.leases"; LEASES_FILE="/var/lib/dhcpd/dhcpd.leases"; TMP_CONFIG="/tmp/$$.tmp.conf"; TMP_TEMPLATE="/tmp/$$.tmp.template.conf"; SUBNET_STEP=32; AMOUNT_OF_DHCPD_LEASES=0; DEBUG_LOGFILE="/var/log/build_groups.log"; DEBUG_IS_ENABLED="yes"; NB_PATH="/etc/nginx/neighbors/common"; EXTRA_CONF="${UPSTREAMS_LOCATION_PATH}/extra-conf" STICKY_CONF="${UPSTREAMS_LOCATION_PATH}/sticky-conf" DISCLIMER_LINE="#This config is auto-generated. DO NOT modify the weight property. If changing the rest of settings, please, remember that you are doing this at your own risk." export $(grep UPSTREAM_KEEPALIVE /.jelenv 2>/dev/null | tr -d '"') >/dev/null [ -z "${UPSTREAM_KEEPALIVE##*[!0-9]*}" ] && UPSTREAM_KEEPALIVE=100 UPSTREAM_KEEPALIVE=${UPSTREAM_KEEPALIVE:-100} [ ! -f "$UPSTREAM_COMMON_CONFIG" ] && touch "$UPSTREAM_COMMON_CONFIG" ############ SERVICE FUNCTIONS ########### writeActionLog=1 function toActionLog(){ local message=$1 if [ "$writeActionLog" -eq 1 ] ;then echo "$message" >> $ACTIONS_LOG fi log "$message" } function getSubnetById(){ CURRENT_GROUP=1 GROUP_ID=$1 for NET in 10.{0..255} do for SUBNET in $NET.{0..255} do ### for IP in $SUBNET.{1..255..$SUBNET_STEP} - new construction not working in old bash3 for ((IP=1;IP<=255;IP+=$SUBNET_STEP)) ### so old stupid way is used ... do if [ $CURRENT_GROUP -eq $GROUP_ID ] then echo $SUBNET.$IP return 0; else CURRENT_GROUP=$[CURRENT_GROUP+1] fi done done done } function generateMapRegexFromIp(){ echo "~"$( $SED -e 's/\./\\\\\\./g' <<< $1 )"\\\\\\:80$" } function reloadConfigs(){ cat "$NGINX_CONFIG_TEMPLATE" > "$NGINX_CONFIG" [ -f "$DHCPD_CONFIG_TEMPLATE" ] && cat "$DHCPD_CONFIG_TEMPLATE" > "$DHCPD_CONFIG" if [ -e "$LEASES_FILE" ]; then set -f rm -f "$LEASES_FILE"; set +f fi toActionLog "- Templates are reloaded" return 0; } function clearHosts(){ set -f rm -Rf "$UPSTREAMS_LOCATION_PATH"/group* set +f echo '' > "$UPSTREAMS_LOCATION_PATH"/common toActionLog "- Upstreams cleaned!" return 0; } function removeDublicates(){ OLDIFS=$IFS IFS=$'\n' nginx_config=( $(cat "$NGINX_CONFIG") ) for ((i=0; i < "${#nginx_config[@]}"; i++)) do if [ "${nginx_config[${i}]}" != "${nginx_config[${i}+1]}" ] then echo "${nginx_config[${i}]}" >> $TMP_CONFIG fi done mv "$TMP_CONFIG" "$NGINX_CONFIG" IFS=$OLDIFS } function getAmountOfDhcpdLeases(){ [ -f "$LEASES_FILE" ] && { AMOUNT_OF_DHCPD_LEASES=$($GREP -c "lease 10" $LEASES_FILE ); echo $AMOUNT_OF_DHCPD_LEASES; } || { echo 0; } } function makeSureNodesReceivedIpsFromDhcpd(){ let local accepted_result=$AMOUNT_OF_DHCPD_LEASES+2; for check in {1..15} do current_result=$(getAmountOfDhcpdLeases); [ $current_result == $accepted_result ] && { break; } || { sleep 3s; [ $check == 15 ] && { toActionLog "- Could not make sure that DHCP works correctly now"; }; } done } ######## MAIN FUNCTIONS ######### function addRangeToDhcpdConfig(){ GROUP_CONFIG=$UPSTREAMS_LOCATION_PATH/$1 if [ -e "$GROUP_CONFIG" ]; then AMOUNT_OF_HOSTS=$( wc -l < $GROUP_CONFIG ) RANGE=$(createDhcpdRange $AMOUNT_OF_HOSTS) insertDhcpdRangeIntoConfig "$RANGE #$1" toActionLog "- DHCP range $RANGE is added to config"; else toActionLog "- ${GROUP_CONFIG} not exists" return 11; fi return 0; } function generateUpstreams(){ GROUP_CONFIG=$UPSTREAMS_LOCATION_PATH/$1 extraConfContent='' if [ -e "$GROUP_CONFIG" ]; then count=1 OLD_IFS=$IFS; IFS=$'\n'; for i in $( sort -u ${GROUP_CONFIG} ) do local ip=$( $SED -nre 's/^([a-z0-9\.\-]{1,})([_| ](([a-z=0-9\ _]{1,})*))?/\1/p' <<< ${i} ) local weight=$( $SED -nre 's/.*([a-z0-9\.\-\=]{1,}[_| ])+([weight=[0-9]{1,}).*/\2/p' <<< ${i} ) local port=$( $SED -nre 's/.*([a-z0-9\.\-\=]{1,}[_| ])+port=([[0-9]{1,}).*/\2/p' <<< ${i} ) [ "x$port" = "x80" ] && port=""; [ -n "$port" ] && port=":${port}"; [ "$2" == "tcp" ] && upstreams[$count]="server ${ip}:BPORT ;" || upstreams[$count]="server ${ip}${port} ${weight};" ((count++)) done IFS=$OLD_IFS upcount=${#upstreams[@]} if [ -f "$NB_PATH" ]; then balancers=($(cat ${NB_PATH} | tr ',' ' ') ) count=${#balancers[@]} for i in $(seq 0 $((${#balancers[@]} - 1))); do backups[$i]="server ${balancers[$i]} backup;" done fi if [ "$2" == "tcp" ]; then echo "${upstreams[@]} ### UPSTREAMPROTO for $1 ###" else [ ! -z "$WEIGHT_CHANGED_FLAG" ] && { [ "$WEIGHT_CHANGED_FLAG" -eq 1 ] && [ -f "$EXTRA_CONF" ] && extraConfContent=$( <${EXTRA_CONF} ); } echo "upstream $1 { ${backups[@]} ${upstreams[@]} $extraConfContent sticky path=/; keepalive $UPSTREAM_KEEPALIVE; } ### UPSTREAMPROTO for $1 ###" fi else toActionLog "- ${GROUP_CONFIG} not exists" ; return 11; fi toActionLog "- upstreams generated" return 0; } function generateDefaultUpstreamLine(){ GROUP_CONFIG=$UPSTREAMS_LOCATION_PATH/$1 extraConfContent='' if [ -e "$GROUP_CONFIG" ]; then count=0 OLD_IFS=$IFS; IFS=$'\n'; for i in $(sort -u ${GROUP_CONFIG} ) do upstreams[$count]="server ${i};" # upstreams[$count]="server $( $SED -nre 's/^([a-z0-9\.\-]{1,})([_| ](([a-z=0-9\ _]{1,})*))?/\1/p' <<< ${i});" ((count++)) done IFS=$OLD_IFS if [ -f "$NB_PATH" ]; then balancers=( $(cat ${NB_PATH} | tr ',' ' ') ) count=${#balancers[@]} for i in $(seq 0 $((${#balancers[@]} - 1))); do backups[$i]="server ${balancers[$i]} backup;" done fi [ -f "$EXTRA_CONF" ] && extraConfContent=$( <${EXTRA_CONF} ); echo "${upstreams[@]} ${backups[@]} $extraConfContent ### DEFUPPROTO for $1 ###" else toActionLog "- ${GROUP_CONFIG} not exists" ; return 11; fi } function createDhcpdRange(){ #argument is hosts amount in subnet AMOUNT_OF_HOSTS=$1 SUBNET_ID=$( $GREP -n NEXT_SUBNET_ID $DHCPD_CONFIG | tail -n 1 | $AWK '{print $3}' ) NEXT_SUBNET_START=$(getSubnetById $SUBNET_ID) ((SUBNET_ID++)) $SED -i "7 c ### NEXT_SUBNET_ID $SUBNET_ID" $DHCPD_CONFIG LAST_SUBNET_IP=$(echo $NEXT_SUBNET_START | $AWK -F "." {'print $4'}) let "LAST_SUBNET_IP +=$AMOUNT_OF_HOSTS-1" NEXT_SUBNET_END="$(echo $NEXT_SUBNET_START | $AWK -F "." '{print $1"."$2"."$3"."}')$LAST_SUBNET_IP" echo "range $NEXT_SUBNET_START $NEXT_SUBNET_END;" } function updateUpstreamSection(){ UPSTREAM_LINE=$(echo -e "\\x09 $1") CHECK_LINE=$( $GREP UPSTREAMPROTO ${NGINX_CONFIG} | $GREP -w $2 | tail -n 1) if [[ $CHECK_LINE == *$2* ]]; then LINE=( $($GREP -n UPSTREAMPROTO ${NGINX_CONFIG} | $GREP -w $2 | tail -n 1 | $AWK -F: '{print $1}') ) $SED -i "$LINE c $UPSTREAM_LINE" $NGINX_CONFIG elif [[ $UPSTREAM_LINE == *server* || $WEIGHT_CHANGED_FLAG -eq 1 ]]; then LINE=( $( $GREP -n UPSTREAMPROTO $NGINX_CONFIG | tail -n 1 | $AWK -F: '{print $1}' ) ) $SED -i "$LINE a $UPSTREAM_LINE" $NGINX_CONFIG [ ! -z "$WEIGHT_CHANGED_FLAG" ] && { [ "$WEIGHT_CHANGED_FLAG" -eq 1 ] && $SED -i "$LINE a $DISCLIMER_LINE" $NGINX_CONFIG ; } fi } function updateMappingsSection(){ MAPPING_LINE=$(echo -e "\\x09 $1") CHECK_LINE=$( $GREP MAPPROTO ${NGINX_CONFIG} | $GREP -w $2 | tail -n 1) if [[ $CHECK_LINE == *$2* ]]; then LINE=( $( $GREP -n MAPPROTO ${NGINX_CONFIG} | $GREP -w $2 | tail -n 1 | $AWK -F: '{print $1}') ) $SED -i "$LINE c $MAPPING_LINE" $NGINX_CONFIG elif [[ $MAPPING_LINE == *:* ]]; then LINE=( $( $GREP -n MAPPROTO $NGINX_CONFIG | tail -n 1 | $AWK -F: '{print $1}') ) $SED -i "$LINE a $MAPPING_LINE" $NGINX_CONFIG fi $SED -i "/DEFUPPROTO/!b;n;n;s/100/$UPSTREAM_KEEPALIVE/" $NGINX_CONFIG } function updateDefaultUpstreamSection(){ UPSTREAM_LINE=$(echo -e "\\x09 $1") CHECK_LINE=$( $GREP DEFUPPROTO $NGINX_CONFIG | $GREP -w $2 | tail -n 1) if [[ $CHECK_LINE == *$2* ]]; then LINE=( $( $GREP -n DEFUPPROTO ${NGINX_CONFIG} | $GREP -w $2 | tail -n 1 | $AWK -F: '{print $1}') ) $SED -i "$LINE c $UPSTREAM_LINE" $NGINX_CONFIG elif [[ $UPSTREAM_LINE == *server* ]]; then LINE=( $( $GREP -n DEFUPPROTO $NGINX_CONFIG | tail -n 1 | $AWK -F: '{print $1}') ) $SED -i "$LINE a $UPSTREAM_LINE" $NGINX_CONFIG [ ! -z "$WEIGHT_CHANGED_FLAG" ] && { [ "$WEIGHT_CHANGED_FLAG" -eq 1 ] && $SED -i "$LINE a $DISCLIMER_LINE" $NGINX_CONFIG ; } fi } function insertDhcpdRangeIntoConfig(){ LINE=( $( $GREP -n range $DHCPD_CONFIG | tail -n 1 | $AWK -F: '{print $1}') ) RANGE_LINE=$(echo -e "\\x09 $1") if [[ $RANGE_LINE == *.* ]]; then $SED -i "$LINE a $RANGE_LINE" $DHCPD_CONFIG fi } function clearGroupFromNginxConfig(){ $GREP -v -E "UPSTREAMPROTO.*$1|MAPPROTO.*$1|DEFUPPROTO.*$1" $NGINX_CONFIG > $TMP_CONFIG mv $TMP_CONFIG $NGINX_CONFIG toActionLog "- Group $1 is removed from config" return 0; } function removeRangeFromDhcpd(){ $GREP -v $1 $DHCPD_CONFIG > $TMP_CONFIG mv $TMP_CONFIG $DHCPD_CONFIG toActionLog "- DHCP range $1 is removed from config" return 0; } function addGroupToUpsreamCommon(){ UPSTREAMS=$(generateUpstreams common) updateUpstreamSection "$UPSTREAMS" common toActionLog "- Updated common upstream section with $UPSTREAMS" return 0; } function addGroupToUpsreamSection(){ UPSTREAMS=$(generateUpstreams $1) updateUpstreamSection "$UPSTREAMS" $1 toActionLog "- Updated group upstream section with $UPSTREAMS" return 0; } function addGroupToDefaultUpsreamSection(){ UPSTREAMS=$(generateDefaultUpstreamLine $1) updateDefaultUpstreamSection "$UPSTREAMS" $1 toActionLog "- Updated default upstream section with $UPSTREAMS" return 0; } function addGroupToMappingsSection(){ MAPPINGS=$(generateMapRegexLine $1) updateMappingsSection "$MAPPINGS" $1 toActionLog "- Updated group mappings section with $UPSTREAMS" return 0; } function generateMapRegexLine(){ GROUP_CONFIG=$UPSTREAMS_LOCATION_PATH/$1 if [ -e ${GROUP_CONFIG} ]; then count=0 OLD_IFS=$IFS; IFS=$'\n'; for i in $(sort ${GROUP_CONFIG} | uniq ) do local ip=$( $SED -nre 's/^([a-z0-9\.\-]{1,})([_| ](([a-z=0-9\ _]{1,})*))?/\1/p' <<< ${i} ) regex_line=$(generateMapRegexFromIp ${ip}) mappings[$count]="$regex_line $1;" ((count++)) done IFS=$OLD_IFS echo "${mappings[@]} ### MAPPROTO for $1 ###" else toActionLog "- ${GROUP_CONFIG} not exists" return 11; fi } function moveIpsFromGroupToCommon(){ GROUP_CONFIG=$UPSTREAMS_LOCATION_PATH/$1 if [ -e "$GROUP_CONFIG" ]; then exec 9<$GROUP_CONFIG while read -u9 line do echo $line >> $UPSTREAM_COMMON_CONFIG done else toActionLog "- ${GROUP_CONFIG} not exists" return 11; fi } function removeGroupIpsFromCommon(){ GROUP_CONFIG=$UPSTREAMS_LOCATION_PATH/$1 if [ -e "$GROUP_CONFIG" ]; then exec 9<$GROUP_CONFIG while read -u9 line do $GREP -v '$line' $UPSTREAM_COMMON_CONFIG > $TMP_CONFIG mv $TMP_CONFIG $UPSTREAM_COMMON_CONFIG done else toActionLog "- ${GROUP_CONFIG} not exists" return 11; fi } ############ TCP Balancing functions ############# function updateTcpUpstreamSection(){ fend_port=$1 bend_port=$2 TCP_UPSTREAM=$(generateUpstreams common tcp) $SED -i -e "s/UPSTREAMPROTO/$TCP_UPSTREAM/g" -e "s/FPORT/$fend_port/g" -e "s/BPORT/$bend_port/g" $TMP_TEMPLATE; } function updateMainNginxConfig(){ cat $TMP_TEMPLATE >> $NGINX_CONFIG; [ -e "$TMP_TEMPLATE" ] && rm $TMP_TEMPLATE; } function addTCPPortMappings(){ if [ -e "$NGINX_TCPMAP_CONFIG" ] then #cat $NGINX_TCPMAP_TEMPLATE > $TMP_TEMPLATE; OLDIFS=$IFS IFS=$'\n' if $GREP pair $NGINX_TCPMAP_CONFIG | $GREP -v '!--' -q ; then echo -e "\ntcp {\n">> $TMP_TEMPLATE; for line in $( $GREP pair $NGINX_TCPMAP_CONFIG | $GREP -v '!--' ) do cat $NGINX_TCPMAP_TEMPLATE >> $TMP_TEMPLATE; fend_port=$($GREP "frontend_port=" <<< $line | cut -d\" -f2) bend_port=$($GREP "backend_port=" <<< $line | cut -d\" -f4) IFS=$OLDIFS updateTcpUpstreamSection "$fend_port" "$bend_port" updateMainNginxConfig done echo "}" >> $NGINX_CONFIG ; fi IFS=$OLDIFS else toActionLog "- mappings.xml not found" fi } function clearTCPPortMappings(){ $SED -i '1,/TCP SECTION/!d' $NGINX_CONFIG } function addCommonHostConfig(){ $GREP -q "^$1$" "$UPSTREAM_COMMON_CONFIG" || echo "$1" >> "$UPSTREAM_COMMON_CONFIG"; } function removeCommonHostConfig (){ $SED -i "/^$1$/d" "$UPSTREAM_COMMON_CONFIG" ; } function weightChanged(){ NGINX_CONFIG_TEMPLATE="/etc/nginx/templates/nginx.conf.traf.distrib.tpl"; if ! grep -q -E 'UPSTREAM' $NGINX_CONFIG ; then rebuildCommonTrafD; [ "$STICKY_NAME" ] && $SED -i "s/sticky/sticky name=${STICKY_NAME}/g" $NGINX_CONFIG ; reloadServiceSilent $SERVICE ; return $?; fi VERBOSE=1; if [ -e "$UPSTREAM_COMMON_CONFIG" ]; then count=1 ; OLD_IFS=$IFS; IFS=$'\n'; for i in $( sort -u ${UPSTREAM_COMMON_CONFIG} ) do ip=$( $SED -nre 's/^([a-z0-9\.\-]{1,})([_| ](([a-z=0-9\ _]{1,})*))?/\1/p' <<< ${i} ) port=$( $SED -nre 's/.*([a-z0-9\.\-\=]{1,}[_| ])+port=([[0-9]{1,}).*/\2/p' <<< ${i} ) weight=$( $SED -nre 's/.*([a-z0-9\.\-\=]{1,}[_| ])+([weight=[0-9]{1,}).*/\2/p' <<< ${i} ) backup=$( $SED -nre 's/.*([a-z0-9\.\-\=]{1,}[_| ])+(backup).*/\2/p' <<< ${i} ) ip_a[$count]=$ip; [ "x$port" = "x80" ] && port=""; [ -n "$port" ] && port=":${port}"; [ "${weight#weight=}" == "0" ] && [ -n "${backup}" ] && weight=; [ -z ${weight#weight=} ] && [ -z "$backup" ] && { log "For $ip value for weight not found" ; toActionLog "For $ip value for weight not found" ; return 0; } || { weight_a[$count]=${weight#weight=} ; backup_a[$count]=${backup} ; port_a[$count]=${port} ; } ((count++)) done IFS=$OLD_IFS fi count=1 ; for c_ip in ${ip_a[@]} do OLD_VAL=$($SED '/^\s*#/d' ${NGINX_CONFIG} | tr '\n' ' ' | $SED -nre "s/.*server\s+${c_ip}[^;.\n]*?weight=([0-9a-z ]{1,})[\s|\;| ].*/\1/p" ) OLD_BACKUP=$(grep -o "${c_ip}${port_a[$count]}[a-z0-9= ]*;" ${NGINX_CONFIG} |grep -o "backup") [ -z "$OLD_VAL" ] && [ -z "$OLD_BACKUP" ] && { log "For $c_ip old value for weight not found" ; toActionLog "For $c_ip old value for weight not found" ; return 0; } old_val[$count]=$OLD_VAL ; old_backup[$count]=$OLD_BACKUP ; ((count++)) ; done for ((count=1; count <= ${#ip_a[@]}; count++)) do log "IP: ${ip_a[$count]}${port_a[$count]} WEIGHT: ${weight_a[$count]} OLD: ${old_val[$count]} ${old_backup}" new_opts=; [ -z ${weight_a[$count]} ] && new_opts="${new_opts} ${backup_a[$count]}" || new_opts="${new_opts} weight=${weight_a[$count]} ${backup_a[$count]}" $SED -i -re "s/${ip_a[$count]}[a-z0-9:= ]*;/${ip_a[$count]}${port_a[$count]} ${new_opts};/" $NGINX_CONFIG ; done reloadServiceSilent $SERVICE ; } function swapHostsHTD(){ VERBOSE=1 local temp=$(getopt -o s:,d:,p: -l source:,destination:,port: -- $@ 2>/dev/null ); [[ $? != 0 ]] && die -q "Terminating..."; eval set -- "$temp"; while [ $# -gt 0 ] do case "$1" in -s | --source ) HOST_SOURCE=$2; shift; ;; -d | --destination ) HOST_DESTINATION=$2; shift; ;; -p | --port ) PORT_DESTINATION=$2; shift; ;; --) shift; break; ;; esac; shift; done; [ -z "$HOST_SOURCE" ] && { writeJSONResponseErr "result=>4065" "message=>SOURCE required" ; return 65; } [ -z "$HOST_DESTINATION" ] && { writeJSONResponseErr "result=>4066" "message=>DESTINATION required" ; return 66; } log "Source: ${HOST_SOURCE}, Destination: ${HOST_DESTINATION}" ; [ -n "$PORT_DESTINATION" ] && { log "Port: ${PORT_DESTINATION}"; } if [ -n "$PORT_DESTINATION" ]; then [ ${PORT_DESTINATION} != "80" ] && PORT_SERVER=":${PORT_DESTINATION}"; $SED -i -re "s/server\s*${HOST_SOURCE}\:?[[:digit:]]+?(\s)/server ${HOST_DESTINATION}${PORT_SERVER}\1/" $NGINX_CONFIG; else $SED -i -re "s/server\s*${HOST_SOURCE}([ |:])/server ${HOST_DESTINATION}\1/" $NGINX_CONFIG; fi # MAP_SOURCE=$( $SED -e 's/\./\\\\./g' <<< $HOST_SOURCE ) # MAP_DESTINATION=$( $SED -e 's/\./\\\\./g' <<< $HOST_DESTINATION ) # $SED -i -re "s/${MAP_SOURCE}/${MAP_DESTINATION}/" $NGINX_CONFIG; $SED -i -re "s/^\s*${HOST_SOURCE}\s*/${HOST_DESTINATION} /" ${UPSTREAM_COMMON_CONFIG} ; if [ -n "$PORT_DESTINATION" ]; then [ ${PORT_DESTINATION} != "80" ] && PORT_COMMON=" port=${PORT_DESTINATION}"; if $GREP -qE "${HOST_DESTINATION}.*[[:space:]]port=" ${UPSTREAM_COMMON_CONFIG} ; then $SED -i "/${HOST_DESTINATION}/{s/[[:space:]]port=[[:digit:]]\+/${PORT_COMMON}/}" ${UPSTREAM_COMMON_CONFIG}; else $SED -i "/${HOST_DESTINATION}/{s/${HOST_DESTINATION}/${HOST_DESTINATION}${PORT_COMMON}/}" ${UPSTREAM_COMMON_CONFIG}; fi fi writeJSONResponseOut "result=>0" "message=>Ok"; } function removeHostHTD(){ VERBOSE=1 local temp=$(getopt -o h: -l host: -- $@ 2>/dev/null ); [[ $? != 0 ]] && die -q "Terminating..."; eval set -- "$temp"; while [ $# -gt 0 ] do case "$1" in -h | --host) HOST_REMOVE=$2; shift; ;; --) shift; break; ;; esac; shift; done; [ -z "$HOST_REMOVE" ] && { writeJSONResponseErr "result=>4065" "message=>SOURCE required" ; return 65; } log "Host: ${HOST_REMOVE}" ; MAP_HREMOVE=$( $SED -e 's/\./\\\\./g' <<< $HOST_REMOVE ) $PERL -i -p0e "s/server\s${HOST_REMOVE}:?([0-9]+)?\s*[:a-z0-9\=]{0,}\s*;//g" $NGINX_CONFIG; $PERL -i -p0e "s/~${MAP_HREMOVE}\\\\:[0-9]+\\$\s*common;//g" $NGINX_CONFIG; $SED -i "/${HOST_REMOVE}\s*/d" ${UPSTREAM_COMMON_CONFIG} ; writeJSONResponseOut "result=>0" "message=>Ok"; } function addNodeHTD(){ VERBOSE=1 local temp=$(getopt -o h:,p: -l host:,port: -- $@ 2>/dev/null ); [[ $? != 0 ]] && die -q "Terminating..."; eval set -- "$temp"; while [ $# -gt 0 ] do case "$1" in -h | --host) HOST_ADD=$2; shift; ;; -p | --port) PORT_ADD=$2; shift; ;; --) shift; break; ;; esac; shift; done; [ -z "$HOST_ADD" ] && { writeJSONResponseErr "result=>4065" "message=>SOURCE required" ; return 65; } log "Host: ${HOST_ADD}" ; [ -n "$PORT_ADD" ] && { log "Port: ${PORT_ADD}" ; } if $GREP -vE "^\s*#" $NGINX_CONFIG | $GREP -q ${HOST_ADD} ; then writeJSONResponseOut "result=>0" "message=>Ok"; return 0 ; fi regex_line=$(generateMapRegexFromIp ${HOST_ADD}) if [ -n "$PORT_ADD" ] && [ "${PORT_ADD}" != "80" ] ; then $SED -i "/### UPSTREAMPROTO for common ###/{s/}\s*###/server ${HOST_ADD}:${PORT_ADD} weight=1; } ###/}" $NGINX_CONFIG; else $SED -i "/### UPSTREAMPROTO for common ###/{s/}\s*###/server ${HOST_ADD} weight=1; } ###/}" $NGINX_CONFIG; fi OLDIFS=$IFS IFS=$'\n' for line in $( $GREP pair $NGINX_TCPMAP_CONFIG | $GREP -v '!--' ) do cat $NGINX_TCPMAP_TEMPLATE > $TMP_TEMPLATE; fend_port=$($GREP "frontend_port=" <<< $line | cut -d\" -f2) bend_port=$($GREP "backend_port=" <<< $line | cut -d\" -f4) IFS=$OLDIFS LINE=$( $GREP -n "listen ${fend_port}" ${NGINX_CONFIG} | tail -n 1 | $AWK -F: '{print $1}' ) ; $SED -i -re "${LINE},/### UPSTREAMPROTO/{s/###/server ${HOST_ADD}:${bend_port}\; ###/}" $NGINX_CONFIG; done IFS=$OLDIFS if [ -n "$PORT_ADD" ] && [ "${PORT_ADD}" != "80" ] ; then echo "${HOST_ADD} port=${PORT_ADD} weight=1" >> $UPSTREAM_COMMON_CONFIG ; else echo "${HOST_ADD} weight=1" >> $UPSTREAM_COMMON_CONFIG ; fi writeJSONResponseOut "result=>0" "message=>Ok"; } function removeStickyHTD(){ [ ! -e ${STICKY_CONF} ] && { touch ${STICKY_CONF}; chmod 666 ${STICKY_CONF}; } perl -i -p0e "s/sticky\s*[:a-zA-Z0-9\s\/\=\.\_]{0,}\s*;//g" $NGINX_CONFIG; writeJSONResponseOut "result=>0" "message=>Ok"; } function addNginxSticky(){ [ ! -e ${STICKY_CONF} ] && { touch ${STICKY_CONF}; chmod 666 ${STICKY_CONF}; } if $GREP -vE "^\s*#" $NGINX_CONFIG | $GREP -q 'sticky' ; then writeJSONResponseOut "result=>0" "message=>Ok"; return 0 ; fi if [ -f ${STICKY_CONF} -a -n "$(cat ${STICKY_CONF})" ]; then STICKY_STRING=$(cat ${STICKY_CONF} |sed -e 's|/|\\/|g' -e 's/"/\\"/g' ); [ -z "$(grep "name=" ${STICKY_CONF})" ] && STICKY_STRING="name=${STICKY_NAME} ${STICKY_STRING}"; $SED -i -re "/### UPSTREAMPROTO for common ###/{s/(keepalive.*)?}\s*###/sticky ${STICKY_STRING}; \1} ###/}" $NGINX_CONFIG; $SED -i "/### DEFUPPROTO for common ###/{s/###/sticky ${STICKY_STRING}; ###/}" $NGINX_CONFIG; else [ "$STICKY_NAME" ] && ADD_NAME="name=${STICKY_NAME}" ; $SED -i -re "/### UPSTREAMPROTO for common ###/{s/(keepalive.*)}\s*###/sticky ${ADD_NAME} path=\/; \1} ###/}" $NGINX_CONFIG; $SED -i "/### DEFUPPROTO for common ###/{s/###/sticky ${ADD_NAME} path=\/; ###/}" $NGINX_CONFIG; writeJSONResponseOut "result=>0" "message=>Ok"; fi } function swapNginxProxyProtocol(){ protocol=$1 if [ "x${protocol}" == "xhttps" ]; then $SED -i -re "/(^|\s)proxy_pass\s/s/proxy_pass\s+http:\/\//proxy_pass https:\/\//" $NGINX_CONFIG; [ -f "$NGINX_SSL_CONFIG" ] && \ $SED -i -re "/(^|\s)proxy_pass\s/s/proxy_pass\s+http:\/\//proxy_pass https:\/\//" $NGINX_SSL_CONFIG; [ -f "$NGINX_SSL_CONFIG.disabled" ] && \ $SED -i -re "/(^|\s)proxy_pass\s/s/proxy_pass\s+http:\/\//proxy_pass https:\/\//" "$NGINX_SSL_CONFIG.disabled"; else $SED -i -re "/(^|\s)proxy_pass\s/s/proxy_pass\s+https:\/\//proxy_pass http:\/\//" $NGINX_CONFIG; [ -f "$NGINX_SSL_CONFIG" ] && \ $SED -i -re "/(^|\s)proxy_pass\s/s/proxy_pass\s+https:\/\//proxy_pass http:\/\//" $NGINX_SSL_CONFIG; [ -f "$NGINX_SSL_CONFIG.disabled" ] && \ $SED -i -re "/(^|\s)proxy_pass\s/s/proxy_pass\s+https:\/\//proxy_pass http:\/\//" "$NGINX_SSL_CONFIG.disabled"; fi writeJSONResponseOut "result=>0" "message=>Ok"; } function setNginxProxyTimeout(){ VERBOSE=1 local temp=$(getopt -o t: -l timeout: -- $@ 2>/dev/null ); [[ $? != 0 ]] && die -q "Terminating..."; eval set -- "$temp"; while [ $# -gt 0 ] do case "$1" in -t | --timeout) TIMEOUT_SET=$2; shift; ;; --) shift; break; ;; esac; shift; done; [ -z "$TIMEOUT_SET" ] && { writeJSONResponseErr "result=>4099" "message=>Missing param" ; return 99; } log "Timeout: ${TIMEOUT_SET}" ; $SED -i -re "/(^|\s)proxy_connect_timeout\s/s/proxy_connect_timeout\s+[0-9]+s/proxy_connect_timeout ${TIMEOUT_SET}s/" $NGINX_CONFIG; writeJSONResponseOut "result=>0" "message=>Ok"; } function setConfigVariables(){ local temp=`getopt -o -n: -l stickyname: -- "$@" 2>>"$JEM_CALLS_LOG"` [[ $? != 0 ]] && die -q "Terminating..."; eval set -- "$temp" while true ; do case "${1}" in -n | --stickyname ) shift; STICKY_NAME="$1"; shift; ;; --) shift; break; ;; esac; done; [ ! -z "$STICKY_NAME" ] && { if $GREP -q "STICKY_NAME" ${META_FILE} ; then $SED -i -re "s/STICKY_NAME\s*=.*/STICKY_NAME=${STICKY_NAME}/g" ${META_FILE}; else echo -e "\nSTICKY_NAME=${STICKY_NAME}" >> ${META_FILE}; fi; } $SED -i -re '/^$/d' ${META_FILE}; return 0; } function setSSLforLB(){ [ -f "$NGINX_SSL_CONFIG" ] && $SED -i -re 's/^\s*include\s*conf.d\/ssl.upstreams.inc/#include conf.d\/ssl.upstreams.inc/' $NGINX_SSL_CONFIG ; [ -f "${NGINX_SSL_CONFIG}.disabled" ] && $SED -i -re 's/^\s*include\s*conf.d\/ssl.upstreams.inc/#include conf.d\/ssl.upstreams.inc/' "${NGINX_SSL_CONFIG}.disabled" ; } function unsetSSLforLB(){ [ -f "$NGINX_SSL_CONFIG" ] && $SED -i -re 's/^\s*#\s*include\s*conf.d\/ssl.upstreams.inc/include conf.d\/ssl.upstreams.inc/' $NGINX_SSL_CONFIG ; [ -f "${NGINX_SSL_CONFIG}.disabled" ] && $SED -i -re 's/^\s*#\s*include\s*conf.d\/ssl.upstreams.inc/include conf.d\/ssl.upstreams.inc/' "${NGINX_SSL_CONFIG}.disabled" ; return 0; } function applyNoBackendsConfig(){ if [ "$(cat "$UPSTREAM_COMMON_CONFIG" | wc -l)" == "0" ]; then if [ -f "${NGINX_NOBACKENDS_CONFIG_TEMPLATE}" ]; then cp -f "${NGINX_NOBACKENDS_CONFIG_TEMPLATE}" "${NGINX_CONFIG}"; fi fi } function rebuildCommon(){ if ! grep -q -E 'upstream\s+default_upstream' "$NGINX_CONFIG" ; then reloadConfigs; fi clearGroupFromNginxConfig common && \ clearTCPPortMappings && \ addGroupToUpsreamCommon && \ addGroupToDefaultUpsreamSection common && \ addGroupToMappingsSection common && \ addTCPPortMappings && \ unsetSSLforLB && \ applyNoBackendsConfig && \ local RETVAL="0" || local RETVAL="1" ; { reloadServiceSilent $SERVICE || restartServiceSilent $SERVICE; } enableService $SERVICE > /dev/null 2>&1 return ${RETVAL} } function rebuildCommonTrafD(){ NGINX_CONFIG_TEMPLATE="/etc/nginx/templates/nginx.conf.traf.distrib.tpl"; reloadConfigs; clearGroupFromNginxConfig common && \ clearTCPPortMappings && \ addGroupToUpsreamCommon && \ addTCPPortMappings && \ enableService $SERVICE > /dev/null 2>&1 && \ setSSLforLB && \ reloadServiceSilent $SERVICE && \ return 0 || return 1; } function addHostToGroup(){ toActionLog "- Add host $host to group $group"; echo "$host" >> "${UPSTREAMS_LOCATION_PATH}/${group}"; } function buildCluster(){ local groupname="$1"; if ! $GREP -q upstream "$NGINX_CONFIG" ; then reloadConfigs; fi clearTCPPortMappings && \ addGroupToMappingsSection common && \ addGroupToUpsreamSection "$groupname" && \ addGroupToMappingsSection "$groupname" && \ addGroupToDefaultUpsreamSection "$groupname" && \ addRangeToDhcpdConfig "$groupname" && \ clearGroupFromNginxConfig common && \ removeGroupIpsFromCommon "$groupname" && \ result=0 || result=1 ; if [ "$result" -eq 0 ] ; then toActionLog "- Group "$groupname" is added to cluster" else toActionLog "- Error was while adding group" fi removeDublicates; restartServiceSilent $SERVICE; enableService $SERVICE > /dev/null 2>&1; toActionLog "- amount of dhcp leases $(getAmountOfDhcpdLeases)"; restartServiceSilent dhcpd; makeSureNodesReceivedIpsFromDhcpd; return $result; } function unbuildCluster(){ local groupname="$1"; [ ! -f "$UPSTREAMS_LOCATION_PATH/$groupname" ] && { return 0; } moveIpsFromGroupToCommon "$groupname" && \ clearGroupFromNginxConfig "$groupname" && \ removeRangeFromDhcpd "$groupname" && \ clearGroupFromNginxConfig common && \ rm "$UPSTREAMS_LOCATION_PATH/$groupname" && \ result=0 || result=1 ; toActionLog "- Group $groupname is removed from cluster and added to common list" removeDublicates; reloadServiceSilent $SERVICE; restartServiceSilent dhcpd; return $result; } function rebuildTCPPortMappings(){ clearTCPPortMappings addTCPPortMappings }