403Webshell
Server IP : 104.129.129.72  /  Your IP : 216.73.216.229
Web Server : LiteSpeed
System : Linux 123answers 5.15.0-143-generic #153-Ubuntu SMP Fri Jun 13 19:10:45 UTC 2025 x86_64
User : answe8064 ( 1002)
PHP Version : 8.2.28
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : ON
Directory :  /opt/installer/services/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /opt/installer/services/clustercontrolgalera
#!/bin/bash

: '
NOTE:
This image is special since it creates multiple nodes using CWM api.
In case of an error, these nodes must be terminated, thus using waitOrStop function is problematic.
Instead a flag will be used, termination will be desided upon the flag.
'

if [ -f "include/startup.sh" ]; then
    . include/startup.sh
elif [ -f "../include/startup.sh" ]; then
    . ../include/startup.sh
fi

rootDir=$(rootDir)
termination_flag=0
nodes_names=()

####### Deploying CWM Nodes #######
## NODE 1
clientId=${CWM_APICLIENTID}
secret=${CWM_APISECRET}
datacenter=${CWM_ZONE}
#last_oct=$((RANDOM % 231 + 10))  # Random number between 10 - 240 to define as last octat for nodes
# Define last octet for first new Node (the rest will be calculated by additional 1 each)
# Extract the last octet from the input variable
origin_last_oct=$(echo "$CWM_IP1" | awk -F '.' '{print $4}')
# Calculate the new value for the last octet
if ((origin_last_oct < 10)); then
  last_oct=$((RANDOM % 230 + 11))
else
  #last_oct=$((RANDOM % (origin_last_oct - 3) + 1))
  last_oct=3
fi

echo "IP of ClusterControl: ${CWM_IP1}" | log
for i in {1..3}
do
node_num=${i}
name="${CWM_NAME}_NODE_${node_num}"
password=${ADMINPASSWORD}
cpu="2B"
ram="2048"
billing="monthly"
managed="0"
backup="0"
power="1"
traffic="3"
disk_size_0="10"
# note: parameters requires url encoding - ubuntu 20
disk_src_0="${CWM_ZONE}:6000C29f313b496da71f669782d04b75"
network_name_0="wan"
network_name_1=$CWM_VLAN1

# Extract the first three octets of the IP address
FIRST_THREE_OCTETS=$(echo $CWM_IP1 | cut -d '.' -f 1-3)
#echo "first free octats: ${FIRST_THREE_OCTETS}" | log

# Set the last octet to a new value
NEW_LAST_OCTET=$((last_oct+i))

# Combine the first three octets and the new last octet to form the new IP address
NEW_IP_ADDRESS="$FIRST_THREE_OCTETS.$NEW_LAST_OCTET"
#echo "New ip address: ${NEW_IP_ADDRESS}" | log

# Print the new IP address
echo "New IP address for node ${i} is: ${NEW_IP_ADDRESS}" | log
eval node_${i}_ip=$NEW_IP_ADDRESS
#eval "echo \"node ${i} new ip address \${node_${i}_ip}\"" | log

# Define the cwm api request
params="datacenter=${datacenter}"
params+="&name=${name}"
params+="&password=${password}"
params+="&cpu=${cpu}"
params+="&ram=${ram}"
params+="&billing=${billing}"
params+="&managed=${managed}"
params+="&backup=${backup}"
params+="&power=${power}"
params+="&traffic=${traffic}"
params+="&disk_size_0=${disk_size_0}"
params+="&disk_src_0=${disk_src_0}"
params+="&network_name_0=${network_name_0}"
params+="&network_name_1=${network_name_1}"
params+="&network_ip_1=${NEW_IP_ADDRESS}"
echo "CWM API: Create new node with IP: ${NEW_IP_ADDRESS} from CWM" | log
response=$(curl -H "AuthClientId: ${clientId}" -H "AuthSecret: ${secret}" -X POST -d "${params}" "https://null.cloudwm.com/service/server")
echo "CWM API RESPONSE:${response}" | log
# Remove spaces
error_code=$(echo "$response" | grep -oP '(?<="code":)\d+')
echo "API CREATE - error code: $error_code" | log
if [ ! -z "$error_code" ]; then
  echo "terminatin_flag switched to 1: error_code of node exists" | log
  echo "error_code for node ${i} creation was ${error_code}" | log
  termination_flag=1
fi

#if [[ ${error_code} -eq 102 ]]
#then
# false - returns non-zero status
#false
#waitOrStop 0 "Failed Node ${i} deploy: generated name already taken"
#fi
#if [[ ${error_code} -eq 117 ]]
#then
# false - returns non-zero status
#false
#waitOrStop 0 "Failed Node ${i} deploy: choosen vlan doesnt exist"
#fi

# If api request was successful grab the command ID:
# Sleep to wait for command appear in CWM
sleep 10
echo "Using CWM API to track ID of creation command for node ${i}"
command_id="${response//[!0-9]/}"
response_command=$(curl -H "AuthClientId: ${clientId}" -H "AuthSecret: ${secret}" "https://null.cloudwm.com/service/queue/${command_id}")
echo "CWM API COMMAND INFO RESPONSE:${response_command}" | log
# Extract name of Node that was created in case termination will be required duting the script
# Extract the value of the "description" field using grep and cut
response_description=$(echo "$response_command" | grep -oP '(?<="description": ")[^"]*')
echo "Description from api respond to command info: ${response_description}" | log

# Extract the substring before " - Create Server" using bash string manipulation
eval node_${i}_name=${response_description%% - Create Server}
temp_node_name=${response_description%% - Create Server}
echo "Extracting Node ${i} name for termination, if required" | log
echo "Node ${i} name: ${temp_node_name}" | log
#eval "echo \"node ${i} new name \${node_${i}_name}\"" | log
nodes_names+=( "$temp_node_name" )
done
#########################################################
if [ "$termination_flag" -eq 0 ]; then

echo "Get ansible Role" | log
ansible-galaxy install severalnines.clustercontrol | log
#waitOrStop 0 "Failed Get ansible Role"
if [ $? -ne 0 ]; then
  termination_flag=1
  echo "Failed: termination_flag=1 Get ansible Role" | log
fi

echo "install MariaDB" | log
installPackage mariadb-server | log
#waitOrStop 0 "Failed install MariaDB - server"
if [ $? -ne 0 ]; then
  termination_flag=1
  echo "Failed install MariaDB - server termination_flag=1" | log
fi
installPackage mariadb-client | log
#waitOrStop 0 "Failed install MariaDB - client"
if [ $? -ne 0 ]; then
  termination_flag=1
  echo "Failed install MariaDB - client termination_flag=1" | log
fi

apt update

echo "Create ansible playbook" | log
cd /root
touch cc.playbook
cat <<EOF > cc.playbook
- hosts: localhost
  roles:
    - { role: severalnines.clustercontrol }
EOF

echo "runing playbook" | log
ansible-playbook cc.playbook | log





#### SSL ####
echo "Installing certbot for apache" | log
installPackage python3-certbot-apache
#waitOrStop 0 "Failed apt install: python-certbot-apache"
if [ $? -ne 0 ]; then
  termination_flag=1
  echo "Failed apt install: python-certbot-apache termination_flag=1" | log
fi


## applying ssl for cc web app ##
systemctl stop apache2.service
execSpecial 3 '(fail|error)' certbot certonly -n --standalone --preferred-challenges http --agree-tos --email ${ADMINEMAIL} -d ${CWM_DOMAIN} ${CWM_DEBUG:+"--test-cert"}

if [[ $? == 1 ]]
then
export certbot_failed=1
echo "Generating self-signed certificate" | log
#waitOrStop 0 "Failed certbot certificate generation"
mkdir /etc/letsencrypt/live
mkdir /etc/letsencrypt/live/${CWM_DOMAIN}
openssl req -x509 -sha256 -newkey rsa:2048 -keyout /etc/letsencrypt/live/${CWM_DOMAIN}/privkey.pem -out /etc/letsencrypt/live/${CWM_DOMAIN}/fullchain.pem -days 1024 -nodes -subj '/CN=localhost'
#waitOrStop 0 "Certificate creation failed"
if [ $? -ne 0 ]; then
  termination_flag=1
  echo "Certificate creation failed termination_flag=1" | log
fi


# Sending log to log server - 45-93-93-142.cloud-xip.com
curl -v -X POST -D -H "Content-Type: application/x-www-form-urlencoded" -d "vm_name='$CWM_NAME'&image_name='$CWM_OS'&vm_owner='$ADMINEMAIL'" http://45-93-93-142.cloud-xip.com


else
export certbot_failed=0
fi

export CWM_DISPLAYED_ADDRESS="${CWM_DOMAIN}"
systemctl start apache2.service
#waitOrStop 0 "Failed to start Apache service"
if [ $? -ne 0 ]; then
  termination_flag=1
  echo "Failed to start Apache service termination_flag=1" | log
fi
tag global-domain-set.success



echo "Reconfigure SSL in Vhost" | log
sed -i "s|^[ \t]*SSLCertificateFile.*|SSLCertificateFile /etc/letsencrypt/live/$CWM_DOMAIN/fullchain.pem|g" /etc/apache2/sites-available/s9s-ssl.conf
sed -i "s|^[ \t]*SSLCertificateKeyFile.*|SSLCertificateKeyFile /etc/letsencrypt/live/$CWM_DOMAIN/privkey.pem|g" /etc/apache2/sites-available/s9s-ssl.conf

#waitOrStop 0 "Failed Reconfigure SSL in Vhost"
if [ $? -ne 0 ]; then
  termination_flag=1  
  echo "Failed Reconfigure SSL in Vhost termination_flag=1" | log
fi
systemctl restart apache2.service
#waitOrStop 0 "Failed restart apache2.service"
if [ $? -ne 0 ]; then
  termination_flag=1
  echo "Failed restart apache2.service termination_flag=1" | log
fi

#### SSL END ####

## Remove Ansible ##
apt-get remove -y ansible


## Create new rpc-key and modify relevant files ##
random_rpc=$(date +%s | sha256sum | base64 | head -c 32 ; echo)
echo "rpc_key=${random_rpc}" >> /etc/cmon.cnf
sed -i "s|define('RPC_TOKEN'|//define('RPC_TOKEN'|g" /var/www/html/clustercontrol/bootstrap.php
echo "define('RPC_TOKEN', '${random_rpc}');" >> /var/www/html/clustercontrol/bootstrap.php



###################################################
## Deploy Galera Cluster ##

# wait until cmon is up
echo "waiting for cmon" | log
while ! nc -z localhost 9501; do
  sleep 1
done

## Check that Nodes are responding ##
# IP addresses to ping
ip1=$node_1_ip
ip2=$node_2_ip
ip3=$node_3_ip
# Loop until all IPs have SSH service
echo "testing ssh for ${ip1}, ${ip2}, ${ip3}, timeout is set for 100*5 seconds" | log
ip_while_counter=0
while true && ((ip_while_counter<100)); do
    if nc -zv "$ip1" 22 >/dev/null && nc -zv "$ip2" 22 >/dev/null && nc -zv "$ip3" 22 >/dev/null; then
        break
    else
        echo "not all servers are listening on 22 yet" | log
        sleep 5
        ip_while_counter=$((ip_while_counter+1))
        echo "counter is ${ip_while_counter}"
    fi
done
echo "All IPs have SSH service." | log

echo "Testing for time out of node deployment" | log
if [[ ip_while_counter -eq 100 ]]
then
false
#waitOrStop 0 "Failed: time out while waiting node deployment"
if [ $? -ne 0 ]; then
  termination_flag=1
  echo "Failed: time out while waiting node deployment termination_flag=1" | log
fi
fi


echo "adding public key to nodes" | log
apt-get install sshpass
ips=($node_1_ip $node_2_ip $node_3_ip)

echo "Coping ssh-keys nodes" | log
for ip in "${ips[@]}"; do
  echo "Copying SSH key to $ip"
  sshpass -p ${ADMINPASSWORD} ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa root@$ip 'cat >> /root/.ssh/authorized_keys' < /root/.ssh/id_rsa.pub
done

#echo "Fix issues with admin user:" | log
#echo "backing up s9s.conf to backup" | log
#mv /etc/s9s.conf /etc/s9s.conf.bak
#echo "Creating dba user to enable admin" | log
#s9s user --create --generate-key --controller="https://localhost:9501" --group=admins dba
#sleep 1
#s9s user --cmon-user=dba --enable admin
#sleep 1
#echo "using reset ccrpc script" | log
#echo "yes" | /var/www/clustercontrol/app/tools/reset-ccrpc.sh
#sleep 10

## Create cmon user named dba
s9s user --create \
  --generate-key \
  --controller="https://localhost:9501" \
  --group=admins dba
if [ $? -ne 0 ]; then
  termination_flag=1
  echo "Failed: s9s user create" | log
fi

echo "Deploying: Run Galera (percona) with 3 servers" | log
s9s cluster --create \
        --cluster-type=galera \
        --nodes="${node_1_ip};${node_2_ip};${node_3_ip}" \
        --vendor=percona \
        --provider-version=5.7 \
        --db-admin-passwd='${ADMINPASSWORD}' \
        --os-user=root \
        --os-key-file=/root/.ssh/id_rsa \
        --cluster-name='Percona XtraDB Cluster 5.7' \
        --wait
if [ $? -ne 0 ]; then
  termination_flag=1
  echo "Failed: s9s deploy galera termination_flag=1" | log
fi

s9s cluster --add-node \
        --cluster-id=1 \
        --nodes="haproxy://${CWM_SERVERIP}" \
        --wait
if [ $? -ne 0 ]; then
  termination_flag=1
  echo "Failed: s9s deploy haproxy termination_flag=1" | log
fi

echo "Adding descriptions" | log
descriptionAppend "Three Nodes should have been created, please make sure you see the nodes in your panel "
descriptionAppend "Run before registration:/var/www/html/clustercontrol/app/tools/reset-ccrpc.sh "
descriptionAppend "clustercontrol web page: ${CWM_DOMAIN}/clustercontrol"
descriptionAppend "cmon config files location: /etc/cmon.cnf"
descriptionAppend "mariaDB user password: ${ADMINPASSWORD}"
descriptionAppend "Galera Cluster users info can be accessed from CC web page after registration"
descriptionAppend "clustercontrol webpage config: /var/www/clustercontrol/bootstrap.php"
descriptionAppend "rpc-key: ${random_rpc}"
descriptionAppend "cmon user(dba) auth: /root/.s9s"
descriptionAppend "Connection String: ${CWM_SERVERIP}:3307 - HAproxy will loadbalance 3306 requests through this port"
descriptionAppend "You should create new mysql user from CC webpage to authenticate at  ${CWM_SERVERIP}:3307"
descriptionAppend " "

fi

if [ "$termination_flag" -eq 1 ]; then
  installPackage jq
  
  for i in "${nodes_names[@]}"
  do
    echo "element in array is: $i" | log
  done

  # Terminate created nodes:
  for i in {1..3}
  do
    # j is used for the nodes_names array access
    j=$((i-1))
    echo "j is: ${j}" | log
    #eval "node_name=\${${nodes_names[$j]}}"
    node_name="${nodes_names[j]}"
    echo "By j indexing, node name now is: ${node_name}" | log 

    if [ ! -z "$node_name" ]; then
      # SLEEP UNTIL ALL NODES ARE CREATED (TO BE TERMINATED)
      echo "Termination: Sleeping until node ${i} responding" | log
      current_ip_var="node_${i}_ip"
      current_ip="${!current_ip_var}"
      ip_while_counter=0
      while true && ((ip_while_counter<100)); do
          if nc -zv "$current_ip" 22 >/dev/null; then
              break
          else
              echo "Termination sleep: ${current_ip} is not listening on 22 yet" | log
              sleep 5
              ip_while_counter=$((ip_while_counter+1))
              echo "counter is ${ip_while_counter}"
          fi
      done
      echo "Termination: All IPs have SSH service." | log

      echo "currently trying to terminate node: ${node_name}" | log
      echo "Fetching server create options with api call to CWM" | log
      curl -H "AuthClientId: ${clientId}" -H "AuthSecret: ${secret}" "https://null.cloudwm.com/service/servers" > listServers.json
      LIST=$(cat listServers.json | jq -r ".[] | select(.name|test(\"$node_name\")) | .id")
      echo "Before for loog of termination Server IDs: ${LIST[@]}" | log
      ## Building list of termination ##
      #echo "Found these images:" | log
      #imageArray=()
      #for imageId in $LIST; do
      #    imageDescription=`cat listServers.json | jq -r '.[] | select(.id|test("'$imageId'")) | .name'`
      #    echo "Image ID: $imageId: $imageDescription" | log
      #    imageArray+=("Image ID: $imageId : $imageDescription")
      #done

      ## Termination ##
      for serverId in $LIST; do
      echo "Terminating server name:${node_name}, id:${serverId}" | log
      confirm="1"
      force="1"
      echo "terminatin node: ${node_name}" | log
      response_termination=$(curl -H "AuthClientId: ${clientId}" -H "AuthSecret: ${secret}" -X DELETE -d "confirm=${confirm}" -d "force=${force}" "https://console.kamatera.com/service/server/${serverId}/terminate")
      echo "CWM TERMINATION for ${node_name} response is: ${response_termination}" | log
      done
    fi
  done

  # exiting
  false
  waitOrStop 0 "Somthing went wrong in Cluster Deploy Script, check the logs"
fi


tag ssl-ready.success
tagScript success
tag apache2.success
tag certbot-apache2.success
tagScript success
exit 0

Youez - 2016 - github.com/yon3zu
LinuXploit