Skip to content

Commit 5155935

Browse files
authored
Add import of cron, domain aliases and add a switch for letsencrypt
Add import of - Cronjobs - Domain aliases and pointers to HestiaCP domain alias Add a switch for enabling Letsencrypt for the imported domains Fix issue with restoring database password because Directadmin save the file with url encoding in the text
1 parent 018b402 commit 5155935

File tree

1 file changed

+149
-38
lines changed

1 file changed

+149
-38
lines changed

bin/v-import-directadmin

Lines changed: 149 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,18 @@
77
# Credits: Maks Usmanov (skamasle), Jaap Marcus (jaapmarcus) and contributors:
88
# Thanks to <https://github.com/Skamasle/sk_da_importer/graphs/contributors>
99

10-
# This script is provided whitout any warranty
10+
# This script is provided without any warranty
1111
# Run at your own risk
1212
# Version 0.1
1313
# This script restore backups from DA to Hestiacp
1414

1515
# shellcheck source=/usr/local/hestia/func/main.sh
16-
source $HESTIA/func/main.sh
16+
source "$HESTIA"/func/main.sh
1717
# shellcheck source=/etc/hestiacp/hestia.conf
1818
source /etc/hestiacp/hestia.conf
1919
# load config file
2020
source_conf "$HESTIA/conf/hestia.conf"
2121

22-
# Check required binaries
2322
if [ ! -e /usr/bin/rsync ] || [ ! -e /usr/bin/file ]; then
2423
echo "#######################################"
2524
echo "rsync not installed, try install it"
@@ -32,10 +31,11 @@ if [ ! -e /usr/bin/rsync ] || [ ! -e /usr/bin/file ]; then
3231
fi
3332
exit 3
3433
fi
35-
3634
# Put this to 0 if you want use bash -x to debug it
3735
debug=1
3836
hestia_package=default
37+
letsencrypt_enable=0
38+
addusertext="IMPORTED"
3939
tmp_dir='tmp_dir_da_backup'
4040
time=$(echo "$time_n_date" | cut -f 1 -d \ )
4141
date=$(echo "$time_n_date" | cut -f 2 -d \ )
@@ -56,6 +56,12 @@ delete_tmp() {
5656
rm -rf /backup/${tmp_dir}
5757
}
5858

59+
# URL decoding function
60+
urldecode() {
61+
local url_encoded="${1//+/ }"
62+
printf '%b' "${url_encoded//%/\\x}"
63+
}
64+
5965
tput setaf 3
6066
echo "#######################################"
6167
echo "# START WITH IMPORT "
@@ -138,13 +144,13 @@ else
138144
exit 3
139145
fi
140146

141-
cd /backup/${tmp_dir}/
147+
cd /backup/${tmp_dir}/ || exit
142148
main_dir=$(pwd)
143149
echo "Access tmp directory $main_dir"
144150
directadmin_user=$(grep username backup/user.conf | cut -d "=" -f 2)
145151
directadmin_usermail=$(grep email backup/user.conf | cut -d "=" -f 2 | grep @)
146152
echo "Get User: $directadmin_user"
147-
if [ -z $directadmin_usermail ]; then
153+
if [ -z "$directadmin_usermail" ]; then
148154
directadmin_usermail=$(grep domain backup/user.conf | cut -d "=" -f 2 | head -n 1)
149155
fi
150156

@@ -156,7 +162,7 @@ fi
156162

157163
echo "Generate random password for $directadmin_user and create Hestiacp Account ..."
158164
new_password=$(generate_password)
159-
$BIN/v-add-user $directadmin_user $new_password $directadmin_usermail $hestia_package
165+
"$BIN"/v-add-user "$directadmin_user" "$new_password" "$directadmin_usermail" $hestia_package $addusertext
160166
if [ "$?" -ne 0 ]; then
161167
tput setaf 1
162168
echo "Error: Unable to create user"
@@ -184,32 +190,33 @@ function run_da_db() {
184190
for da_db in $da_db_list; do
185191

186192
database_name=${da_db::-5}
187-
grep -w $database_name server_dbs
193+
grep -w "$database_name" server_dbs
188194
if [ $? == "1" ]; then
189195
if [ -e "backup/${database_name}.sql" ]; then
190196

191197
#Get the database name
192-
db=$(grep db_collation backup/${da_db} | tr '&' '\n ' | grep SCHEMA_NAME | cut -d "=" -f 2)
198+
db=$(grep db_collation backup/"${da_db}" | tr '&' '\n ' | grep SCHEMA_NAME | cut -d "=" -f 2)
193199

194200
tput setaf 2
195201
echo " Create and restore ${db} "
196202
tput sgr0
197203
mysql -e "CREATE DATABASE $db"
198-
mysql ${db} < backup/${db}.sql
204+
mysql "${db}" < backup/"${db}".sql
199205
#Get all the users of the database
200206
while IFS= read -r line; do
201207

202-
selectdb_line=$(echo $line | grep passwd)
208+
selectdb_line=$(echo "$line" | grep passwd)
203209
if [ ! -z "$selectdb_line" ]; then
204210

205-
db_user=$(echo $selectdb_line | tr '&' '\n ' | grep ${directadmin_user} | cut -d "=" -f 1)
206-
md5=$(echo $selectdb_line | tr '&' '\n ' | grep passwd | cut -d "=" -f 2)
211+
db_user=$(echo "$selectdb_line" | tr '&' '\n ' | grep "${directadmin_user}" | cut -d "=" -f 1)
212+
encoded_md5=$(echo "$selectdb_line" | tr '&' '\n ' | grep passwd | cut -d "=" -f 2)
213+
md5=$(urldecode "$encoded_md5")
207214

208215
echo "DB: $db"
209216
echo "udb: $db_user"
210217
echo "Password: ${md5}"
211218

212-
echo "DB='$db' DBUSER='$db_user' MD5='$md5' HOST='localhost' TYPE='mysql' CHARSET='UTF8' U_DISK='0' SUSPENDED='no' TIME='$time' DATE='$data'" >> /usr/local/hestia/data/users/$directadmin_user/db.conf
219+
echo "DB='$db' DBUSER='$db_user' MD5='$md5' HOST='localhost' TYPE='mysql' CHARSET='UTF8' U_DISK='0' SUSPENDED='no' TIME='$time' DATE='$date'" >> /usr/local/hestia/data/users/"$directadmin_user"/db.conf
213220
fi
214221

215222
done < "backup/${da_db}"
@@ -218,11 +225,11 @@ function run_da_db() {
218225
tput setaf 2
219226
echo "Rebuild databases files for $directadmin_user"
220227
tput sgr0
221-
$BIN/v-rebuild-databases $directadmin_user
228+
"$BIN"/v-rebuild-databases "$directadmin_user"
222229
fi
223230
else
224231
tput setaf 1
225-
echo "Error: Cant restore database $db alredy exists in mysql server"
232+
echo "Error: Cant restore database $db already exists in mysql server"
226233
tput sgr0
227234
fi
228235
done
@@ -250,39 +257,39 @@ for directadmin_domain in $directadmin_domain_list; do
250257
tput setaf 2
251258
echo "Add $directadmin_domain if not exists"
252259
tput sgr0
253-
$BIN/v-add-domain ${directadmin_user} $directadmin_domain
260+
"$BIN"/v-add-domain "${directadmin_user}" "$directadmin_domain"
254261
if [ $? -ne 0 ]; then
255262
tput setaf 4
256263
echo "Domain $directadmin_domain already added in some account, skip..."
257264
tput sgr0
258-
elif [ -d /home/${directadmin_user}/web/${directadmin_domain} ]; then
265+
elif [ -d /home/"${directadmin_user}"/web/"${directadmin_domain}" ]; then
259266
echo "Domain $directadmin_domain added, restoring files"
260-
echo $directadmin_domain >> restored_domains
261-
rm -f /home/$directadmin_user/web/$directadmin_domain/public_html/index.html
262-
rm -f /home/$directadmin_user/web/$directadmin_domain/public_html/robots.txt
267+
echo "$directadmin_domain" >> restored_domains
268+
rm -f /home/"$directadmin_user"/web/"$directadmin_domain"/public_html/index.html
269+
rm -f /home/"$directadmin_user"/web/"$directadmin_domain"/public_html/robots.txt
263270

264271
public_sync_count=0
265-
rsync -av domains/${directadmin_domain}/public_html/ /home/$directadmin_user/web/$directadmin_domain/public_html 2>&1 \
272+
rsync -av domains/"${directadmin_domain}"/public_html/ /home/"$directadmin_user"/web/"$directadmin_domain"/public_html 2>&1 \
266273
| while read file_dm; do
267274
public_sync_count=$(($public_sync_count + 1))
268275
echo -en "-- $public_sync_count restored files\r"
269276
done
270277

271-
chown ${directadmin_user}:${directadmin_user} -R /home/${directadmin_user}/web/${directadmin_domain}/public_html
272-
chmod 751 /home/${directadmin_user}/web/${directadmin_domain}/public_html
278+
chown "${directadmin_user}":"${directadmin_user}" -R /home/"${directadmin_user}"/web/"${directadmin_domain}"/public_html
279+
chmod 751 /home/"${directadmin_user}"/web/"${directadmin_domain}"/public_html
273280

274281
if [[ -L "domains/${directadmin_domain}/private_html" && -d "domains/${directadmin_domain}/private_html" ]]; then
275282
echo "private_html is a symlink to public_html so we don't need to copy it."
276283
else
277284
private_sync_count=0
278285

279-
rsync -av domains/${directadmin_domain}/private_html/ /home/$directadmin_user/web/$directadmin_domain/private 2>&1 \
286+
rsync -av domains/"${directadmin_domain}"/private_html/ /home/"$directadmin_user"/web/"$directadmin_domain"/private 2>&1 \
280287
| while read file_dm; do
281288
private_sync_count=$(($private_sync_count + 1))
282289
echo -en "-- $private_sync_count restored files\r"
283290
done
284-
chown ${directadmin_user}:${directadmin_user} -R /home/${directadmin_user}/web/${directadmin_domain}/private
285-
chmod 751 /home/${directadmin_user}/web/${directadmin_domain}/private
291+
chown "${directadmin_user}":"${directadmin_user}" -R /home/"${directadmin_user}"/web/"${directadmin_domain}"/private
292+
chmod 751 /home/"${directadmin_user}"/web/"${directadmin_domain}"/private
286293
fi
287294
else
288295
echo "Ups.. cant restore or add domain: $directadmin_domain"
@@ -300,41 +307,145 @@ echo "Start restoring mails"
300307
tput sgr0
301308
function da_restore_imap_pass() {
302309
#DirectAdmin passw is SHA512-CRYPT
303-
da_orig_pass=$(grep -w $1 backup/$2/email/passwd | tr ':' ' ' | cut -d " " -f2)
304-
echo ${da_orig_pass}
310+
da_orig_pass=$(grep -w "$1" backup/"$2"/email/passwd | tr ':' ' ' | cut -d " " -f2)
311+
echo "${da_orig_pass}"
305312
USER_DATA=$HESTIA/data/users/${3}/
306313
update_object_value "mail/${2}" 'ACCOUNT' "${1}" '$MD5' "{SHA512-CRYPT}$da_orig_pass"
307314
echo "Password for $1@$2 restored"
308315
}
309316
echo cat restored_domains
310317
if [ -e restored_domains ]; then
311318
cat restored_domains | while read da_mail_domain; do
312-
if [ "$(ls -A imap/${da_mail_domain}/)" ]; then
319+
if [ "$(ls -A imap/"${da_mail_domain}"/)" ]; then
313320
tput setaf 2
314321
echo "Found Imap for ${da_mail_domain}"
315322
tput sgr0
316-
ls -1 imap/${da_mail_domain}/ | while read da_imap; do
323+
ls -1 imap/"${da_mail_domain}"/ | while read da_imap; do
317324
tmp_pass=$(generate_password)
318-
$BIN/v-add-mail-account $directadmin_user $da_mail_domain $da_imap tmp_pass
325+
"$BIN"/v-add-mail-account "$directadmin_user" "$da_mail_domain" "$da_imap" "$tmp_pass"
319326
if [ "$debug" != 0 ]; then
320-
rsync -av imap/${da_mail_domain}/${da_imap}/Maildir/ /home/${directadmin_user}/mail/${da_mail_domain}/${da_imap} 2>&1 \
327+
rsync -av imap/"${da_mail_domain}"/"${da_imap}"/Maildir/ /home/"${directadmin_user}"/mail/"${da_mail_domain}"/"${da_imap}" 2>&1 \
321328
| while read backup_file_dm; do
322329
sk_sync=$((sk_sync + 1))
323330
echo -en "-- $sk_sync restored files\r"
324331
done
325332
echo " "
326333
else
327-
rsync imap/${da_mail_domain}/${da_imap}/Maildir/ /home/${directadmin_user}/mail/${da_mail_domain}/${da_imap}
334+
rsync imap/"${da_mail_domain}"/"${da_imap}"/Maildir/ /home/"${directadmin_user}"/mail/"${da_mail_domain}"/"${da_imap}"
328335
fi
329-
chown ${directadmin_user}:mail -R /home/${directadmin_user}/mail/${da_mail_domain}/${da_imap}
330-
find /home/$directadmin_user/mail/$da_mail_domain -type f -name 'dovecot*' -delete
331-
da_restore_imap_pass $da_imap $da_mail_domain $directadmin_user
336+
chown "${directadmin_user}":mail -R /home/"${directadmin_user}"/mail/"${da_mail_domain}"/"${da_imap}"
337+
find /home/"$directadmin_user"/mail/"$da_mail_domain" -type f -name 'dovecot*' -delete
338+
da_restore_imap_pass "$da_imap" "$da_mail_domain" "$directadmin_user"
332339
done
333340

334-
$BIN/v-rebuild-mail-domain $directadmin_user $da_mail_domain
341+
"$BIN"/v-rebuild-mail-domain "$directadmin_user" "$da_mail_domain"
335342
fi
336343
done
337344
fi
345+
346+
tput setaf 3
347+
echo "#######################################"
348+
echo "# CRON JOBS "
349+
echo "#######################################"
350+
tput sgr0
351+
352+
# Restore cron jobs
353+
if [ -f "backup/crontab.conf" ]; then
354+
while IFS= read -r cron_line; do
355+
# Skip empty lines and comments
356+
[[ -z "$cron_line" || "$cron_line" =~ ^#.*$ ]] && continue
357+
358+
# Check if the line is an environment variable
359+
if [[ "$cron_line" =~ ^[A-Z]+= ]]; then
360+
# Export environment variable
361+
# echo "Setting environment variable: $cron_line"
362+
export "$cron_line"
363+
continue
364+
fi
365+
366+
# Remove the cron job identifier and extract cron job details
367+
if [[ "$cron_line" =~ ^[0-9]+= ]]; then
368+
cron_line=${cron_line#*=}
369+
fi
370+
371+
# Extract cron job details (handle cases where command contains spaces)
372+
IFS=' ' read -r min hour day month wday command <<< "$cron_line"
373+
374+
# Ensure it is a valid cron job line (i.e., min, hour, day, month, wday should be numeric or valid cron symbols)
375+
if ! [[ "$min" =~ ^[\*0-9,-/]+$ && "$hour" =~ ^[\*0-9,-/]+$ && "$day" =~ ^[\*0-9,-/]+$ && "$month" =~ ^[\*0-9,-/]+$ && "$wday" =~ ^[\*0-9,-/]+$ ]]; then
376+
echo "Invalid cron job format: $cron_line"
377+
continue
378+
fi
379+
380+
# Reconstruct the command part
381+
command="${cron_line#"${min}" "${hour}" "${day}" "${month}" "${wday}" }"
382+
383+
echo "Adding cron job for user $directadmin_user: $cron_line"
384+
"$BIN"/v-add-cron-job "$directadmin_user" "$min" "$hour" "$day" "$month" "$wday" "$command"
385+
done < "backup/crontab.conf"
386+
else
387+
echo "No cron jobs found to restore."
388+
fi
389+
390+
tput setaf 3
391+
echo "#######################################"
392+
echo "# DOMAIN ALIASES "
393+
echo "#######################################"
394+
tput sgr0
395+
396+
# Restore domain aliases
397+
domain_base_dir="backup"
398+
399+
if [ -d "$domain_base_dir" ]; then
400+
for domain_subdir in "$domain_base_dir"/*/; do
401+
domain_pointers_file="$domain_subdir/domain.pointers"
402+
if [ -f "$domain_pointers_file" ]; then
403+
while IFS= read -r pointer_line; do
404+
# Skip empty lines and comments
405+
[[ -z "$pointer_line" || "$pointer_line" =~ ^#.*$ ]] && continue
406+
407+
# Extract alias and type
408+
alias_domain=$(echo "$pointer_line" | cut -d'=' -f1)
409+
alias_type=$(echo "$pointer_line" | awk -F'type=' '{print $2}')
410+
411+
if [[ "$alias_type" == "alias" || "$alias_type" == "pointer" ]]; then
412+
domain_name=$(basename "$domain_subdir")
413+
echo "Adding domain alias $alias_domain for user $directadmin_user on domain $domain_name"
414+
"$BIN"/v-add-web-domain-alias "$directadmin_user" "$domain_name" "$alias_domain" no
415+
else
416+
echo "Skipping non-alias type for $alias_domain: $alias_type"
417+
fi
418+
done < "$domain_pointers_file"
419+
fi
420+
done
421+
else
422+
echo "No domain directories found to restore."
423+
fi
424+
425+
tput setaf 3
426+
echo "#######################################"
427+
echo "# ENABLE LETSENCRYPT "
428+
echo "#######################################"
429+
tput sgr0
430+
431+
# Enable Let's Encrypt for each domain
432+
if [ "$letsencrypt_enable" = 1 ]; then
433+
for directadmin_domain in $directadmin_domain_list; do
434+
echo "Enabling Let's Encrypt for $directadmin_domain"
435+
letsencrypt_output=$("$BIN"/v-add-letsencrypt-domain "$directadmin_user" "$directadmin_domain" '' yes 2>&1)
436+
echo "$letsencrypt_output"
437+
if echo "$letsencrypt_output" | grep -q "Error: mail domain"; then
438+
echo "Error with Let's Encrypt: $letsencrypt_output"
439+
echo "Retrying Let's Encrypt without mail domain for $directadmin_domain"
440+
"$BIN"/v-add-letsencrypt-domain "$directadmin_user" "$directadmin_domain" '' no
441+
else
442+
echo "Let's Encrypt enabled for $directadmin_domain"
443+
fi
444+
done
445+
else
446+
echo "Let's Encrypt is not enabled for any domain."
447+
fi
448+
338449
delete_tmp
339450
tput sgr0
340451
tput setaf 2

0 commit comments

Comments
 (0)