Rewrite call method
This commit is contained in:
parent
c952f1c372
commit
c928752bbb
|
@ -8,74 +8,76 @@ for _command in openssl curl; do
|
||||||
done
|
done
|
||||||
unset _command
|
unset _command
|
||||||
|
|
||||||
declare AliAccessKeyId AliAccessKeySecret
|
# aliapi_rpc <http_method> <host> <api_version> <api_action> [<--key> <value>...]
|
||||||
_AliAccessKeyId=$AliAccessKeyId
|
|
||||||
_AliAccessKeySecret=$AliAccessKeySecret
|
|
||||||
|
|
||||||
# aliapi_rpc <host> <http_method> <api_version> <api_action> [api_custom_key] [api_custom_value]
|
|
||||||
aliapi_rpc() {
|
aliapi_rpc() {
|
||||||
_AliAccessKeyId=$AliAccessKeyId
|
if [[ ! -v AliAccessKeyId || ! -v AliAccessKeySecret ]]; then
|
||||||
_AliAccessKeySecret=$AliAccessKeySecret
|
echo "Aliyun OpenAPI SDK: 'AliAccessKeyId' or 'AliAccessKeySecret' environment variable not found" >&2
|
||||||
if [[ -z $_AliAccessKeyId ]]; then
|
return 3
|
||||||
echo "Aliyun OpenAPI SDK: 'AliAccessKeyId' environment variable not found or null"
|
|
||||||
return 61
|
|
||||||
fi
|
|
||||||
if [[ -z $_AliAccessKeySecret ]]; then
|
|
||||||
echo "Aliyun OpenAPI SDK: 'AliAccessKeySecret' environment variable not found or null"
|
|
||||||
return 62
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! [[ $# -eq 4 || $# -eq 6 ]];then
|
if [[ $# -lt 4 ]];then
|
||||||
echo "Aliyun OpenAPI SDK: aliapi_rpc() not enough parameters"
|
echo "Aliyun OpenAPI SDK: aliapi_rpc() not enough parameters" >&2
|
||||||
return 66
|
return 2
|
||||||
fi
|
fi
|
||||||
local _http_host=$1 _http_method=$2 _api_action=$4 _api_version=$3
|
|
||||||
|
local _AliAccessKeyId=$AliAccessKeyId _AliAccessKeySecret=$AliAccessKeySecret
|
||||||
|
|
||||||
|
local _http_method=$1
|
||||||
# 兼容 BusyBox
|
# 兼容 BusyBox
|
||||||
# shellcheck disable=SC2018,SC2019
|
# shellcheck disable=SC2018,SC2019
|
||||||
_http_method=$(tr "a-z" "A-Z" <<< "$_http_method")
|
_http_method=$(tr "a-z" "A-Z" <<< "$_http_method")
|
||||||
# 公共查询参数键
|
shift
|
||||||
local _api_common_key=(
|
local _http_host=$1
|
||||||
"AccessKeyId"
|
shift
|
||||||
"Action"
|
local _api_version=$1
|
||||||
"Format"
|
shift
|
||||||
"SignatureMethod"
|
local _api_action=$1
|
||||||
"SignatureVersion"
|
shift
|
||||||
"SignatureNonce"
|
|
||||||
"Timestamp"
|
local -A _api_params
|
||||||
"Version"
|
_api_params=(
|
||||||
|
["AccessKeyId"]=$_AliAccessKeyId
|
||||||
|
["Action"]=$_api_action
|
||||||
|
["Format"]="JSON"
|
||||||
|
["SignatureMethod"]="HMAC-SHA1"
|
||||||
|
["SignatureVersion"]="1.0"
|
||||||
|
["SignatureNonce"]=$(_aliapi_signature_nonce)
|
||||||
|
["Timestamp"]=$(_aliapi_timestamp_rpc)
|
||||||
|
["Version"]=$_api_version
|
||||||
)
|
)
|
||||||
# 公共查询参数值
|
# 解析其余参数
|
||||||
local _ali_common_value=(
|
while [[ $# -ne 0 ]]
|
||||||
"$_AliAccessKeyId"
|
do
|
||||||
"$_api_action"
|
case $1 in
|
||||||
"JSON"
|
--*)
|
||||||
"HMAC-SHA1"
|
if [[ $# -le 1 ]]; then
|
||||||
"1.0"
|
echo "Aliyun OpenAPI SDK: aliapi_rpc() '$1' has no value" >&2
|
||||||
"$(_ali_signature_nonce)"
|
return 2
|
||||||
"$(_ali_timestamp_rpc)"
|
fi
|
||||||
"$_api_version"
|
_api_params[${1:2}]="$2"
|
||||||
)
|
shift
|
||||||
declare -a _ali_custom_key _ali_custom_value _ali_key _ali_value
|
shift
|
||||||
# 自定义查询参数键值
|
;;
|
||||||
read -r -a _ali_custom_key <<< "$5"
|
*)
|
||||||
read -r -a _ali_custom_value <<< "$6"
|
echo "Aliyun OpenAPI SDK: aliapi_rpc() Unknown parameter: $1" >&2
|
||||||
# 合并查询键值
|
return 2
|
||||||
read -r -a _ali_key <<< "${_api_common_key[*]} ${_ali_custom_key[*]}"
|
;;
|
||||||
read -r -a _ali_value <<< "${_ali_common_value[*]} ${_ali_custom_value[*]}"
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
local _query_str=""
|
local _query_str=""
|
||||||
local _key _value
|
local _key _value
|
||||||
local i
|
for _key in "${!_api_params[@]}"; do
|
||||||
for (( i = 0; i < ${#_ali_key[@]}; ++i )); do
|
_value=${_api_params[$_key]}
|
||||||
_key=${_ali_key[$i]}
|
|
||||||
_value=${_ali_value[$i]}
|
|
||||||
# 参数值如果是以 () 结束,代表需要执行函数获取值,如果函数不存在,使用原始值。
|
# 参数值如果是以 () 结束,代表需要执行函数获取值,如果函数不存在,使用原始值。
|
||||||
[[ ($(grep -E "^.+\(\)$" <<< "$_value") == "$_value" && $(type -t "${_value:0:-2}") == "function") ]] && _value=$(${_value:0:-2})
|
[[ ($(grep -E "^.+\(\)$" <<< "$_value") == "$_value" && $(type -t "${_value:0:-2}") == "function") ]] && _value=$(${_value:0:-2})
|
||||||
_value=$(_urlencode "$_value")
|
_value=$(_aliapi_urlencode "$_value")
|
||||||
_query_str+="$_key=$_value&"
|
_query_str+="$_key=$_value&"
|
||||||
done
|
done
|
||||||
local _ali_signature_value
|
|
||||||
_ali_signature_value=$(_ali_signature_rpc "$_http_method" "$_query_str")
|
local _signature
|
||||||
_query_str+="Signature=$(_urlencode "$_ali_signature_value")"
|
_signature=$(_aliapi_signature_rpc "$_http_method" "$_query_str")
|
||||||
|
_query_str+="Signature=$(_aliapi_urlencode "$_signature")"
|
||||||
local _curl_out _http_code _http_url="https://$_http_host/?$_query_str"
|
local _curl_out _http_code _http_url="https://$_http_host/?$_query_str"
|
||||||
_curl_out=$(mktemp)
|
_curl_out=$(mktemp)
|
||||||
_http_code=$(curl --location --silent --show-error --request "$_http_method" --output "$_curl_out" --write-out "%{http_code}" --connect-timeout 3 "$_http_url") && cat "$_curl_out" - <<< ""
|
_http_code=$(curl --location --silent --show-error --request "$_http_method" --output "$_curl_out" --write-out "%{http_code}" --connect-timeout 3 "$_http_url") && cat "$_curl_out" - <<< ""
|
||||||
|
@ -83,11 +85,11 @@ aliapi_rpc() {
|
||||||
[[ $_http_code -eq 200 ]] && return 0 || return 1
|
[[ $_http_code -eq 200 ]] && return 0 || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
_ali_signature_rpc() {
|
_aliapi_signature_rpc() {
|
||||||
local _http_method=$1 _str _query_str _sign_str
|
local _http_method=$1 _str _query_str _sign_str
|
||||||
_str=$(echo -n "$2" | tr "&" "\n" | sort)
|
_str=$(LC_ALL=C echo -n "$2" | tr "&" "\n" | sort)
|
||||||
_query_str=$(echo -n "$_str" | tr "\n" "&")
|
_query_str=$(echo -n "$_str" | tr "\n" "&")
|
||||||
_sign_str="$_http_method&$(_urlencode "/")&$(_urlencode "$_query_str")"
|
_sign_str="$_http_method&$(_aliapi_urlencode "/")&$(_aliapi_urlencode "$_query_str")"
|
||||||
echo -n "$_sign_str" | openssl sha1 -hmac "$_AliAccessKeySecret&" -binary | openssl base64 -e
|
echo -n "$_sign_str" | openssl sha1 -hmac "$_AliAccessKeySecret&" -binary | openssl base64 -e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,14 +98,21 @@ _aliapi_timestamp_rpc() {
|
||||||
date -u -Iseconds
|
date -u -Iseconds
|
||||||
}
|
}
|
||||||
|
|
||||||
_ali_signature_nonce() {
|
_aliapi_signature_nonce() {
|
||||||
date "+%s%N"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_urlencode() {
|
_aliapi_urlencode() {
|
||||||
local result
|
local result
|
||||||
result=$(curl --get --silent --output /dev/null --write-out "%{url_effective}" --data-urlencode "=$1" "")
|
result=$(curl --get --silent --output /dev/null --write-out "%{url_effective}" --data-urlencode "=$1" "")
|
||||||
|
result="${result//+/%20}" # 替换 + 为 %20
|
||||||
echo "${result#*\?}"
|
echo "${result#*\?}"
|
||||||
}
|
}
|
||||||
|
|
||||||
[[ $# -ne 0 ]] && aliapi_rpc "$@"
|
if [[ ${#BASH_SOURCE[@]} -eq 1 ]]; then
|
||||||
|
set -euf -o pipefail
|
||||||
|
if [[ $# -eq 0 ]]; then
|
||||||
|
echo "$0 <http_method> <host> <api_version> <api_action> [<--key> <value>...]" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
aliapi_rpc "$@"
|
||||||
|
fi
|
||||||
|
|
40
README.md
40
README.md
|
@ -1,13 +1,10 @@
|
||||||
# Aliyun OpenAPI Shell SDK
|
# Aliyun OpenAPI Bash SDK
|
||||||
|
|
||||||
这是一个非官方的阿里云 OpenAPI Shell SDK,方便 Shell 脚本调用阿里云 OpenAPI,SDK 主要实现了自动计算 OpenAPI 的请求签名。
|
这是一个非官方的阿里云 OpenAPI Bash SDK,方便 Bash 脚本调用阿里云 OpenAPI,SDK 主要实现了自动计算 OpenAPI 的请求签名。
|
||||||
|
|
||||||
虽然阿里云官方有 [AliyunCLI](https://github.com/aliyun/aliyun-cli),可以在 Shell 环境下使用阿里云 OpenAPI,但是并不支持某些 API (比如 SSL 证书)。
|
|
||||||
对于存储空间有限的嵌入式设备,Shell SDK 可能是更好的选择。
|
|
||||||
|
|
||||||
理论上支持所有阿里云 RPC OpenAPI,暂不支持 RESTful OpenAPI,将来可能会支持。
|
理论上支持所有阿里云 RPC OpenAPI,暂不支持 RESTful OpenAPI,将来可能会支持。
|
||||||
|
|
||||||
> 这可能是最好用的 Aliyun OpenAPI Shell SDK
|
> 这可能是最好用的 Aliyun OpenAPI Bash SDK
|
||||||
|
|
||||||
## 依赖
|
## 依赖
|
||||||
|
|
||||||
|
@ -25,11 +22,10 @@
|
||||||
```bash
|
```bash
|
||||||
# Output: JsonString
|
# Output: JsonString
|
||||||
# Retrun Code: 0 = HTTP_STATUS_CODE == 200 | 1 = HTTP_STATUS_CODE != 200
|
# Retrun Code: 0 = HTTP_STATUS_CODE == 200 | 1 = HTTP_STATUS_CODE != 200
|
||||||
aliapi_rpc <host> <http_method> <api_version> <api_action> [api_custom_key] [api_custom_value]
|
aliapi_rpc <http_method> <host> <api_version> <api_action> [<--key> <value>...]
|
||||||
# api_custom_key 和 api_custom_value 可以省略,但不允许只传递其中一个。
|
|
||||||
```
|
```
|
||||||
|
|
||||||
PS: `AliyunOpenApiSDK.sh` 支持独立执行,参数与函数参数一致。
|
PS: `AliyunOpenApiSDK.sh` 支持作为脚本独立执行,脚本参数与函数参数一致。
|
||||||
|
|
||||||
**示例:**
|
**示例:**
|
||||||
|
|
||||||
|
@ -43,29 +39,17 @@ export AliAccessKeySecret="<AliAccessKeySecret>"
|
||||||
# 导入 SDK
|
# 导入 SDK
|
||||||
source AliyunOpenApiSDK.sh
|
source AliyunOpenApiSDK.sh
|
||||||
|
|
||||||
# 自定义请求参数的键值数组顺序要一一对应,数组成员不能包含空格。
|
# 如果值以 () 结尾,那么 SDK 会假设它是一个已定义函数,获取值时会判断函数是否存在并执行,如果不存在则使用原始值。
|
||||||
# 自定义值支持自定义函数,如果你需要包含空格或者读取文件等操作,可以声明一个自定义函数,像下面这样。
|
|
||||||
# 如果自定义值数组成员以 () 结尾,SDK 在获取值的时候会判断自定义函数是否存在并执行,如果不存在则使用原始值。
|
|
||||||
|
|
||||||
# 自定义请求参数的键
|
|
||||||
api_custom_key=(
|
|
||||||
"CurrentPage"
|
|
||||||
"ShowSize"
|
|
||||||
)
|
|
||||||
# 自定义请求参数的值
|
|
||||||
api_custom_value=(
|
|
||||||
"1"
|
|
||||||
"get_show_size()" # 解析参数时会执行函数 (所以最后提交的值是 50)
|
|
||||||
)
|
|
||||||
|
|
||||||
get_show_size() {
|
get_show_size() {
|
||||||
echo 50
|
echo 50
|
||||||
}
|
}
|
||||||
|
|
||||||
# 获取 SSL 证书列表:https://help.aliyun.com/document_detail/126511.html
|
# 获取 SSL 证书列表:https://help.aliyun.com/document_detail/126511.html
|
||||||
aliapi_rpc "cas.aliyuncs.com" "GET" "2018-07-13" "DescribeUserCertificateList" "${api_custom_key[*]}" "${api_custom_value[*]}"
|
# 解析参数时会执行函数 (所以 ShowSize 的值是 50)
|
||||||
|
aliapi_rpc GET cas.aliyuncs.com 2018-07-13 DescribeUserCertificateList --CurrentPage 1 --ShowSize "get_show_size()"
|
||||||
# $? == 0 代表 HTTP CODE == 200 反之 $? == 1
|
# $? == 0 代表 HTTP CODE == 200 反之 $? == 1
|
||||||
# 只要 curl 的返回代码 == 0 就会返回接收到的数据
|
# 只要 curl 的退出代码 == 0 就会返回接收到的数据
|
||||||
if [[ $? -eq 0 ]]; then
|
if [[ $? -eq 0 ]]; then
|
||||||
# 执行成功
|
# 执行成功
|
||||||
else
|
else
|
||||||
|
@ -73,8 +57,6 @@ else
|
||||||
fi
|
fi
|
||||||
```
|
```
|
||||||
|
|
||||||
更多示例请参考 [examples](https://github.com/Hill-98/aliyun-openapi-shell-sdk/tree/master/examples) 下的文件
|
更多示例请参考 [examples](https://github.com/Hill-98/aliyun-openapi-bash-sdk/tree/master/examples) 下的文件
|
||||||
|
|
||||||
如果你有好的示例,欢迎提交 [PR](https://github.com/Hill-98/aliyun-openapi-shell-sdk/pulls)
|
如果你有好的示例,欢迎提交 [PR](https://github.com/Hill-98/aliyun-openapi-bash-sdk/pulls)。
|
||||||
|
|
||||||
如果你有建议 / BUG 要反馈,请提交 [Issue](https://github.com/Hill-98/aliyun-openapi-shell-sdk/issues)
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ ACME_ENV_LIST=(
|
||||||
)
|
)
|
||||||
# 检查环境变量是否存在
|
# 检查环境变量是否存在
|
||||||
for value in "${ACME_ENV_LIST[@]}" ; do
|
for value in "${ACME_ENV_LIST[@]}" ; do
|
||||||
declare -p "$value" &>/dev/null || exit 1
|
[[ ! -v "$value" ]] || exit 1
|
||||||
done
|
done
|
||||||
unset value
|
unset value
|
||||||
|
|
||||||
|
@ -45,58 +45,22 @@ DOMAIN_LIST=(
|
||||||
"example.example.com"
|
"example.example.com"
|
||||||
)
|
)
|
||||||
|
|
||||||
api_custom_key=(
|
|
||||||
"CurrentPage"
|
|
||||||
"ShowSize"
|
|
||||||
)
|
|
||||||
api_custom_value=(
|
|
||||||
"1"
|
|
||||||
"50"
|
|
||||||
)
|
|
||||||
# 获取证书列表
|
# 获取证书列表
|
||||||
result=$(aliapi_rpc "cas.aliyuncs.com" "GET" "2018-07-13" "DescribeUserCertificateList" "${api_custom_key[*]}" "${api_custom_value[*]}" || exit 101)
|
result=$(aliapi_rpc GET cas.aliyuncs.com 2018-07-13 DescribeUserCertificateList --CurrentPage 1 --ShowSize 50) || exit 101
|
||||||
# 使用 jq 处理返回的 JSON 数据并提取出匹配当前证书域名的证书列表的 ID,用于稍后的删除旧证书操作。
|
# 使用 jq 处理返回的 JSON 数据并提取出匹配当前证书域名的证书列表的 ID,用于稍后的删除旧证书操作。
|
||||||
cert_list=$(jq -cr ".CertificateList|map(select(.common == \"$DOMAIN\"))|map(.id)|.[]" <<< "$result")
|
cert_list=$(jq -cr ".CertificateList|map(select(.common == \"$DOMAIN\"))|map(.id)|.[]" <<< "$result")
|
||||||
|
|
||||||
api_custom_key=(
|
|
||||||
"Cert"
|
|
||||||
"Key"
|
|
||||||
"Name"
|
|
||||||
)
|
|
||||||
# 使用自定义函数获取证书和密钥,保证内容可以被完整的传递。
|
|
||||||
api_custom_value=(
|
|
||||||
"get_cert()"
|
|
||||||
"get_key()"
|
|
||||||
"$CERT_NAME"
|
|
||||||
)
|
|
||||||
# 上传新的证书
|
# 上传新的证书
|
||||||
aliapi_rpc "cas.aliyuncs.com" "GET" "2018-07-13" "CreateUserCertificate" "${api_custom_key[*]}" "${api_custom_value[*]}" || exit 102
|
aliapi_rpc GET cas.aliyuncs.com 2018-07-13 CreateUserCertificate --Cert "get_cert()" --Key "get_key()" --Name "$CERT_NAME" || exit 102
|
||||||
|
|
||||||
# 设置 CDN 域名列表使用新的证书
|
# 设置 CDN 域名列表使用新的证书
|
||||||
for domain in "${DOMAIN_LIST[@]}"; do
|
for _domain in "${DOMAIN_LIST[@]}"; do
|
||||||
api_custom_key=(
|
aliapi_rpc GET cdn.aliyuncs.com 2018-05-10 SetDomainServerCertificate --DomainName "$_domain" --ServerCertificateStatus on --CertName "$CERT_NAME" --CertType cas || exit 103
|
||||||
"DomainName"
|
|
||||||
"ServerCertificateStatus"
|
|
||||||
"CertName"
|
|
||||||
"CertType"
|
|
||||||
)
|
|
||||||
api_custom_value=(
|
|
||||||
"$domain"
|
|
||||||
"on"
|
|
||||||
"$CERT_NAME"
|
|
||||||
"cas"
|
|
||||||
)
|
|
||||||
aliapi_rpc "cdn.aliyuncs.com" "GET" "2018-05-10" "SetDomainServerCertificate" "${api_custom_key[*]}" "${api_custom_value[*]}" || exit 103
|
|
||||||
done
|
done
|
||||||
unset domain
|
unset _domain
|
||||||
|
|
||||||
# 删除旧的证书
|
# 删除旧的证书
|
||||||
for id in ${cert_list}; do
|
for _id in ${cert_list}; do
|
||||||
api_custom_key=(
|
aliapi_rpc GET cas.aliyuncs.com 2018-07-13 DeleteUserCertificate --CertId "$_id" || exit 104
|
||||||
"CertId"
|
|
||||||
)
|
|
||||||
api_custom_value=(
|
|
||||||
"$id"
|
|
||||||
)
|
|
||||||
aliapi_rpc "cas.aliyuncs.com" "GET" "2018-07-13" "DeleteUserCertificate" "${api_custom_key[*]}" "${api_custom_value[*]}" || exit 104
|
|
||||||
done
|
done
|
||||||
unset id
|
unset _id
|
||||||
|
|
Loading…
Reference in New Issue