Skip to content

Instantly share code, notes, and snippets.

@vizv
Last active August 13, 2020 14:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save vizv/e55741af2b16acad861a424549bae520 to your computer and use it in GitHub Desktop.
Save vizv/e55741af2b16acad861a424549bae520 to your computer and use it in GitHub Desktop.
用于在维护后启动 TFCLOUD 实例的脚本
#!/bin/bash -e
# 用于在维护后启动 TFCLOUD 实例的脚本
# 获取更新:https://gist.github.com/vizv/e55741af2b16acad861a424549bae520
# boot.sh Copyright (C) 2020 Viz <viz@linux.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
###
### 常量和初始化
###
BASE_URL='https://idc.yuxan.cn'
COOKIE_FILE='tmp/cookie'
mkdir --parents "$(dirname "$COOKIE_FILE")"
###
### 助手函数
###
msg_good() {
echo "[+] $*"
}
msg_bad() {
echo "[-] $*"
}
die() {
echo "[!] $*" >&2
exit "${EXIT_STATUS:=1}"
}
inspect() {
[ -z "$DEBUG_FLAG" ] && return
echo "[?] $1=${!1}"
}
request() {
curl --silent \
--location \
--show-error \
--retry 5 \
--cookie 'tmp/cookie' \
--cookie-jar 'tmp/cookie' \
"$@"
}
###
### 登录操作
###
msg_good '获取 CSRF 令牌...'
CSRF_TOKEN=$(
request 'https://idc.tf/clientarea.php' \
| grep csrfToken \
| grep --only-matching '[0-9a-f]\{40\}' \
|| die '获取 CSRF 令牌:请求失败'
)
inspect CSRF_TOKEN
[ -n "$CSRF_TOKEN" ] || die '获取 CSRF 令牌:令牌为空'
msg_good '等待登录...'
printf '邮箱:'
read -r EMAIL
inspect EMAIL
printf '密码:(不会回显)'
read -rs PASSWORD
echo
inspect PASSWORD
msg_good '登录管理面板...'
PANEL_PAGE=$(
request "${BASE_URL}/dologin.php" \
--form "username=${EMAIL}" \
--form "password=${PASSWORD}" \
--form "token=${CSRF_TOKEN}" \
|| die '登录管理面板:请求失败'
)
# inspect PANEL_PAGE
grep --silent '账户或密码错误' <<<"$PANEL_PAGE" \
&& die '登录管理面板:用户名或密码错误'
USER=$(
grep '欢迎回来' <<<"$PANEL_PAGE" \
| sed 's/^.*"h5 push-30-r">\([^<]\+\)<.*$/\1/g' \
| head -1
)
inspect USER
msg_good "登录成功,用户:${USER}"
###
### 选择服务
###
# 正则表达式:字段
## 1: ID
R_ID='id=\([0-9]\+\)'
## 2: 服务名
R_NAME='<strong[^>]\+>\([^<]\+\)<\/strong>'
## 3: 实例名
R_INSTANCE='实例名:\([^/]\+\)'
## 4: 公网 IP
R_PUB_IP='公网IP:\([^<]\+\)'
## 5: 价格
R_PRICE='data-order="\([^"]\+\)"'
## 6: 付款周期
R_PERIOD='\([^<]\+\)'
## 7: 下次付款
R_DUEDATE='<span class="hidden">\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\)<\/span>'
## 8: 状态
R_STATUS='<span class="label status [^"]\+">\([^<]\+\)<\/span>'
# 正则表达式:列
R_COL1="<td>${R_NAME}<br \/><a[^>]\+>${R_INSTANCE} \/ ${R_PUB_IP}<\/a><\/td>"
R_COL2="<td ${R_PRICE} class=\"hidden-sm hidden-xs\">[^<]\+<\/td>"
R_COL3="<td class=\"hidden-sm hidden-xs\">${R_PERIOD}<\/td>"
R_COL4="<td class=\"hidden-sm hidden-xs\">${R_DUEDATE}[^<]\+<\/td>"
R_COL5="<td class=\"hidden\">${R_STATUS}<\/td>"
# 正则表达式:行
R_HEAD="<tr onclick=\"clickableSafeRedirect([^;]\+;${R_ID}[^)]\+)\">"
R_COLS="${R_COL1}\s*${R_COL2}\s*${R_COL3}\s*${R_COL4}\s*${R_COL5}"
# 正则表达式:服务
R_SERVICE_PATTERN="${R_HEAD}\s*${R_COLS}"
R_SERVICE_REPLACE="\1,\2,\3,\4,¥\5,\6,\7,\8"
msg_good '读取服务列表...'
TABLE_HEAD='ID,服务名,实例名,公网 IP,价格,付款周期,下次付款,状态'
TABLE_DATA=$(
request "${BASE_URL}/clientarea.php?action=services" \
| tr '\n' '\r' \
| grep --only-matching "$R_SERVICE_PATTERN" \
| sed "s/${R_SERVICE_PATTERN}/${R_SERVICE_REPLACE}/g" \
|| die '读取服务列表:请求失败'
)
inspect TABLE_DATA
column --table \
--separator=',' \
--table-columns="$TABLE_HEAD" \
<<<"$TABLE_DATA"
msg_good '等待选择服务...'
printf '输入需要启动的服务 ID:'
read -r SERVICE_ID
inspect SERVICE_ID
grep --silent "^[0-9]\+$" <<<"$SERVICE_ID" \
|| die '选择服务:无效的 ID'
grep --silent "^$SERVICE_ID," <<<"$TABLE_DATA" \
|| die '选择服务:所选服务不在服务列表中'
###
### 执行开机操作
###
OPERATION='boot'
msg_good '执行开机操作...'
REQUEST_QUERY="id=${SERVICE_ID}&modop=custom&a=${OPERATION}"
REQUEST_STATUS=$(
request "${BASE_URL}/clientarea.php?action=productdetails&${REQUEST_QUERY}" \
--output page \
--write-out '%{http_code}' \
|| die '执行开机操作:请求失败'
)
inspect REQUEST_STATUS
[ "$REQUEST_STATUS" = '200' ] || die '执行开机操作:失败'
msg_good '执行开机操作:成功'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment