From 517baa3235cb5f94ffa866884cd65fa1147c3d10 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Mon, 29 Apr 2024 22:54:31 +1000 Subject: [PATCH 01/16] test DNS for v2 (actual) --- dnsapi/dns_selectel.sh | 479 +++++++++++++++++++++++++++++++++++------ 1 file changed, 418 insertions(+), 61 deletions(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 1b09882d..f5b6b1b9 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -1,10 +1,29 @@ #!/usr/bin/env sh +# переменные, которые должны быть определены перед запуском +# export SL_Ver="v1" - версия API: 'v2' (actual) или 'v1' (legacy). +# По-умолчанию: v2 +# Если SL_Ver="v1" +# export SL_Key="API_KEY" - Токен Selectel (API key) +# Посмотреть или создать можно в панели управления в правом верхнем углу откройте меню Профиль и настройки -> Ключи API. +# https://my.selectel.ru/profile/apikeys +# Если SL_Ver="v2" +# export SL_Expire=60 - время жизни token в минутах (0-1440). +# По-умолчанию: 1400 минут +# export SL_Login_ID= - номер аккаунта в панели управления; +# export SL_Project_Name= - имя проекта. +# export SL_Login_name= - имя сервисного пользователя. Посмотреть имя можно в панели управления: +# в правом верхнем углу откройте меню → Профиль и настройки → раздел Управление пользователями → вкладка Сервисные пользователи +# export SL_Pswd='pswd' - пароль сервисного пользователя, можно посмотреть при создании пользователя или изменить на новый. +# Все эти переменные будут сохранены ~/.acme.sh/account.conf и будут использоваться повторно при необходимости. # -#SL_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" -# +# Авторизация описана в: +# https://developers.selectel.ru/docs/control-panel/authorization/ +# https://developers.selectel.com/docs/control-panel/authorization/ -SL_Api="https://api.selectel.ru/domains/v1" +SL_Api="https://api.selectel.ru/domains" +auth_uri="https://cloud.api.selcloud.ru/identity/v3/auth/tokens" +_sl_sep='#' ######## Public functions ##################### @@ -13,17 +32,16 @@ dns_selectel_add() { fulldomain=$1 txtvalue=$2 - SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}" - - if [ -z "$SL_Key" ]; then - SL_Key="" - _err "You don't specify selectel.ru api key yet." - _err "Please create you key and try again." + #if ! _sl_init_vars; then + if ! _sl_init_vars; then return 1 fi - - #save the api key to the account conf file. - _saveaccountconf_mutable SL_Key "$SL_Key" + _debug2 SL_Ver "$SL_Ver" + _secure_debug3 SL_Key "$SL_Key" + _debug2 SL_Expire "$SL_Expire" + _debug2 SL_Login_Name "$SL_Login_Name" + _debug2 SL_Login_ID "$SL_Login_ID" + _debug2 SL_Project_Name "$SL_Project_Name" _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -35,11 +53,68 @@ dns_selectel_add() { _debug _domain "$_domain" _info "Adding record" - if _sl_rest POST "/$_domain_id/records/" "{\"type\": \"TXT\", \"ttl\": 60, \"name\": \"$fulldomain\", \"content\": \"$txtvalue\"}"; then - if _contains "$response" "$txtvalue" || _contains "$response" "record_already_exists"; then + if [ "$SL_Ver" = "v2" ]; then + _ext_srv1="/zones/" + _ext_srv2="/rrset/" + _text_tmp=$(echo "$txtvalue" | sed -En "s/[\"]*([^\"]*)/\1/p") + _debug txtvalue "$txtvalue" + _text_tmp='\"'$_text_tmp'\"' + _debug _text_tmp "$_text_tmp" + _data="{\"type\": \"TXT\", \"ttl\": 60, \"name\": \"${fulldomain}.\", \"records\": [{\"content\":\"$_text_tmp\"}]}" + elif [ "$SL_Ver" = "v1" ]; then + _ext_srv1="/" + _ext_srv2="/records/" + _data="{\"type\":\"TXT\",\"ttl\":60,\"name\":\"$fulldomain\",\"content\":\"$txtvalue\"}" + else + #not valid + _err "Error. Unsupported version API $SL_Ver" + return 1 + fi + _ext_uri="${_ext_srv1}$_domain_id${_ext_srv2}" + _debug3 _ext_uri "$_ext_uri" + _debug3 _data "$_data" + + if _sl_rest POST "$_ext_uri" "$_data"; then + if _contains "$response" "$txtvalue"; then _info "Added, OK" return 0 fi + if _contains "$response" "already_exists"; then + # запись TXT с $fulldomain уже существует + if [ "$SL_Ver" = "v2" ]; then + # надо добавить к существующей записи еще один content + # + # считать записи rrset + _debug "Getting txt records" + _sl_rest GET "${_ext_uri}" + # Если в данной записи, есть текстовое значение $txtvalue, + # то все хорошо, добавлять ничего не надо и результат успешный + if _contains "$response" "$txtvalue"; then + _info "Added, OK" + _info "Txt record ${fulldomain} со значением ${txtvalue} already exists" + return 0 + fi + # группа \1 - полная запись rrset; группа \2 - значение records:[{"content":"\"v1\""},{"content":"\"v2\""}",...], а именно {"content":"\"v1\""},{"content":"\"v2\""}",... + _record_seg="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*${fulldomain}[^}]*records[^}]*\[(\{[^]]*\})\][^}]*}).*/\1/p")" + _record_array="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*${fulldomain}[^}]*records[^}]*\[(\{[^]]*\})\][^}]*}).*/\2/p")" + # record id + _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" + _tmp_str="${_record_array},{\"content\":\"${_text_tmp}\"}" + _data="{\"ttl\": 60, \"records\": [${_tmp_str}]}" + _debug3 _record_seg "$_record_seg" + _debug3 _record_array "$_record_array" + _debug3 _record_array "$_record_id" + _debug3 _data "$_data" + # вызов REST API PATCH + if _sl_rest PATCH "${_ext_uri}${_record_id}" "$_data"; then + _info "Added, OK" + return 0 + fi + elif [ "$SL_Ver" = "v1" ]; then + _info "Added, OK" + return 0 + fi + fi fi _err "Add txt record error." return 1 @@ -49,16 +124,17 @@ dns_selectel_add() { dns_selectel_rm() { fulldomain=$1 txtvalue=$2 - - SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}" - - if [ -z "$SL_Key" ]; then - SL_Key="" - _err "You don't specify slectel api key yet." - _err "Please create you key and try again." + #SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}" + if ! _sl_init_vars "nosave"; then return 1 fi - + _debug2 SL_Ver "$SL_Ver" + _secure_debug3 SL_Key "$SL_Key" + _debug2 SL_Expire "$SL_Expire" + _debug2 SL_Login_Name "$SL_Login_Name" + _debug2 SL_Login_ID "$SL_Login_ID" + _debug2 SL_Project_Name "$SL_Project_Name" + # _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" @@ -67,32 +143,90 @@ dns_selectel_rm() { _debug _domain_id "$_domain_id" _debug _sub_domain "$_sub_domain" _debug _domain "$_domain" - + # + if [ "$SL_Ver" = "v2" ]; then + _ext_srv1="/zones/" + _ext_srv2="/rrset/" + elif [ "$SL_Ver" = "v1" ]; then + _ext_srv1="/" + _ext_srv2="/records/" + else + #not valid + _err "Error. Unsupported version API $SL_Ver" + return 1 + fi + # _debug "Getting txt records" - _sl_rest GET "/${_domain_id}/records/" - + _ext_uri="${_ext_srv1}$_domain_id${_ext_srv2}" + _debug3 _ext_uri "$_ext_uri" + _sl_rest GET "${_ext_uri}" + # if ! _contains "$response" "$txtvalue"; then _err "Txt record not found" return 1 fi - - _record_seg="$(echo "$response" | _egrep_o "[^{]*\"content\" *: *\"$txtvalue\"[^}]*}")" - _debug2 "_record_seg" "$_record_seg" + # + if [ "$SL_Ver" = "v2" ]; then + _record_seg="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\1/gp")" + _record_arr="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\3/p")" + #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2)" + elif [ "$SL_Ver" = "v1" ]; then + _record_seg="$(echo "$response" | _egrep_o "[^{]*\"content\" *: *\"$txtvalue\"[^}]*}")" + # record id + #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2)" + else + #not valid + _err "Error. Unsupported version API $SL_Ver" + return 1 + fi + _debug3 "_record_seg" "$_record_seg" if [ -z "$_record_seg" ]; then _err "can not find _record_seg" return 1 fi - - _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2)" - _debug2 "_record_id" "$_record_id" + # record id + _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" if [ -z "$_record_id" ]; then _err "can not find _record_id" return 1 fi - - if ! _sl_rest DELETE "/$_domain_id/records/$_record_id"; then - _err "Delete record error." - return 1 + _debug3 "_record_id" "$_record_id" + # delete all record type TXT with text $txtvalue + if [ "$SL_Ver" = "v2" ]; then + # actual + #del_txt='it47Qq60vJuzQJXb9WEaapciTwtt1gb_14gm1ubwzrA'; + _new_arr="$(echo "$_record_seg" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\3/gp" | sed -En "s/(\},\{)/}\n{/gp" | sed "/${txtvalue}/d" | sed ":a;N;s/\n/,/;ta")" + # uri record for DEL or PATCH + _del_uri="${_ext_uri}${_record_id}" + if [ -z "$_new_arr" ]; then + # удалить запись + if ! _sl_rest DELETE "${_del_uri}"; then + _err "Delete record error: ${_del_uri}." + else + info "Delete record success: ${_del_uri}." + fi + else + # обновить запись, удалив content + _data="{\"ttl\": 60, \"records\": [${_new_arr}]}" + _debug3 _data "$_data" + # вызов REST API PATCH + if _sl_rest PATCH "${_del_uri}" "$_data"; then + _info "Patched, OK: ${_del_uri}" + else + _err "Patched record error: ${_del_uri}." + fi + fi + else + # legacy + for _one_id in $_record_id; do + _del_uri="${_ext_uri}${_one_id}" + _debug2 _ext_uri "$_del_uri" + if ! _sl_rest DELETE "${_del_uri}"; then + _err "Delete record error: ${_del_uri}." + else + info "Delete record success: ${_del_uri}." + fi + done fi return 0 } @@ -105,51 +239,114 @@ dns_selectel_rm() { # _domain_id=sdjkglgdfewsdfg _get_root() { domain=$1 + # + if [ "$SL_Ver" = 'v1' ]; then + # version API 1 + if ! _sl_rest GET "/"; then + return 1 + fi + i=2 + p=1 + while true; do + #h=$(printf "%s" "$domain" | cut -d . -f $i-100) + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + return 1 + fi - if ! _sl_rest GET "/"; then + if _contains "$response" "\"name\" *: *\"$h\","; then + #_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") + _domain=$h + _debug "Getting domain id for $h" + if ! _sl_rest GET "/$h"; then + _err "Error read records of all domains $SL_Ver" + return 1 + fi + _domain_id="$(echo "$response" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\":" | cut -d : -f 2)" + return 0 + fi + p=$i + i=$(_math "$i" + 1) + done + _err "Error read records of all domains $SL_Ver" return 1 - fi - - i=2 - p=1 - while true; do - h=$(printf "%s" "$domain" | cut -d . -f $i-100) - _debug h "$h" - if [ -z "$h" ]; then + elif [ "$SL_Ver" = "v2" ]; then + # version API 2 + _ext_uri='/zones/' + domain="${domain}." + _debug "domain:: " "$domain" + # read records of all domains + if ! _sl_rest GET "$_ext_uri"; then #not valid + _err "Error read records of all domains $SL_Ver" return 1 fi - - if _contains "$response" "\"name\" *: *\"$h\","; then - _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) - _domain=$h - _debug "Getting domain id for $h" - if ! _sl_rest GET "/$h"; then + i=2 + p=1 + while true; do + h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) + _debug h "$h" + if [ -z "$h" ]; then + #not valid + _err "The domain was not found among the registered ones" return 1 fi - _domain_id="$(echo "$response" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\":" | cut -d : -f 2)" - return 0 - fi - p=$i - i=$(_math "$i" + 1) - done - return 1 + + _domain_record=$(echo "$response" | sed -En "s/.*(\{[^}]*id[^}]*\"name\" *: *\"$h\"[^}]*}).*/\1/p") + _debug "_domain_record:: " "$_domain_record" + if [ -n "$_domain_record" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") + _domain=$h + _debug "Getting domain id for $h" + #_domain_id="$(echo "$_domain_record" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\":" | cut -d : -f 2 | sed -En "s/\"([^\"]*)\"/\1\p")" + _domain_id=$(echo "$_domain_record" | sed -En "s/\{[^}]*\"id\" *: *\"([^\"]*)\"[^}]*\}/\1/p") + return 0 + fi + p=$i + i=$(_math "$i" + 1) + done + #not valid + _err "Error read records of all domains $SL_Ver" + return 1 + else + #not valid + _err "Error. Unsupported version API $SL_Ver" + return 1 + fi } +################################################################# +# use: method add_url body _sl_rest() { m=$1 ep="$2" data="$3" - _debug "$ep" - export _H1="X-Token: $SL_Key" + _token=$(_get_auth_token) + #_debug "$_token" + if [ -z "$_token" ]; then + _err "BAD key or token $ep" + return 1 + fi + if [ "$SL_Ver" = v2 ]; then + _h1_name="X-Auth-Token" + else + _h1_name='X-Token' + fi + export _H1="${_h1_name}: ${_token}" export _H2="Content-Type: application/json" + _debug3 "Full URI: " "$SL_Api/${SL_Ver}${ep}" + _debug3 "_H1:" "$_H1" + _debug3 "_H2:" "$_H2" if [ "$m" != "GET" ]; then _debug data "$data" - response="$(_post "$data" "$SL_Api/$ep" "" "$m")" + response="$(_post "$data" "$SL_Api/${SL_Ver}${ep}" "" "$m")" else - response="$(_get "$SL_Api/$ep")" + response="$(_get "$SL_Api/${SL_Ver}${ep}")" fi if [ "$?" != "0" ]; then @@ -159,3 +356,163 @@ _sl_rest() { _debug2 response "$response" return 0 } + +#################################################################3 +# use: +_get_auth_token() { + if [ "$SL_Ver" = 'v1' ]; then + # token for v1 + _debug "Token v1" + _token_keystone=$SL_Key + elif [ "$SL_Ver" = 'v2' ]; then + # token for v2. Get a token for calling the API + _debug "Keystone Token v2" + token_v2=$(_readaccountconf_mutable SL_Token_V2) + if [ -n "$token_v2" ]; then + # The structure with the token was considered. Let's check its validity + # field 1 - SL_Login_Name + # field 2 - token keystone + # field 3 - SL_Login_ID + # field 4 - SL_Project_Name + # field 5 - Receipt time + # separator - ';' + _login_name=$(_getfield "$token_v2" 1 "$_sl_sep") + _token_keystone=$(_getfield "$token_v2" 2 "$_sl_sep") + _project_name=$(_getfield "$token_v2" 4 "$_sl_sep") + _receipt_time=$(_getfield "$token_v2" 5 "$_sl_sep") + _login_id=$(_getfield "$token_v2" 3 "$_sl_sep") + _debug3 _login_name "$_login_name" + _debug3 _login_id "$_login_id" + _debug3 _project_name "$_project_name" + _debug3 _receipt_time "$(date -d @"$_receipt_time" -u)" + # check the validity of the token for the user and the project and its lifetime + #_dt_diff_minute=$(( ( $(EPOCHSECONDS)-$_receipt_time )/60 )) + _dt_diff_minute=$((($(date +%s) - _receipt_time) / 60)) + _debug3 _dt_diff_minute "$_dt_diff_minute" + [ "$_dt_diff_minute" -gt "$SL_Expire" ] && unset _token_keystone + if [ "$_project_name" != "$SL_Project_Name" ] || [ "$_login_name" != "$SL_Login_Name" ] || [ "$_login_id" != "$SL_Login_ID" ]; then + unset _token_keystone + fi + _debug "Get exists token" + fi + if [ -z "$_token_keystone" ]; then + # the previous token is incorrect or was not received, get a new one + _debug "Update (get new) token" + _data_auth="{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":{\"user\":{\"name\":\"${SL_Login_Name}\",\"domain\":{\"name\":\"${SL_Login_ID}\"},\"password\":\"${SL_Pswd}\"}}},\"scope\":{\"project\":{\"name\":\"${SL_Project_Name}\",\"domain\":{\"name\":\"${SL_Login_ID}\"}}}}}" + #_secure_debug2 "_data_auth" "$_data_auth" + export _H1="Content-Type: application/json" + # body url [needbase64] [POST|PUT|DELETE] [ContentType] + _result=$(_post "$_data_auth" "$auth_uri") + _token_keystone=$(grep 'x-subject-token' "$HTTP_HEADER" | sed -nE "s/[[:space:]]*x-subject-token:[[:space:]]*([[:print:]]*)(\r*)/\1/p") + #echo $_token_keystone > /root/123456.qwe + #_dt_curr=$EPOCHSECONDS + _dt_curr=$(date +%s) + SL_Token_V2="${SL_Login_Name}${_sl_sep}${_token_keystone}${_sl_sep}${SL_Login_ID}${_sl_sep}${SL_Project_Name}${_sl_sep}${_dt_curr}" + _saveaccountconf_mutable SL_Token_V2 "$SL_Token_V2" + fi + else + # token set empty for unsupported version API + _token_keystone="" + fi + printf -- "%s" "$_token_keystone" +} + +################################################################# +# use: [non_save] +_sl_init_vars() { + _non_save="${1}" + _debug2 _non_save "$_non_save" + + _debug "First init variables" + # version API + SL_Ver="${SL_Ver:-$(_readaccountconf_mutable SL_Ver)}" + if [ -z "$SL_Ver" ]; then + SL_Ver="v2" + fi + if ! [ "$SL_Ver" = "v1" ] && ! [ "$SL_Ver" = "v2" ]; then + _err "You don't specify selectel.ru API version." + _err "Please define specify API version." + fi + _debug2 SL_Ver "$SL_Ver" + + if [ "$SL_Ver" = "v1" ]; then + # token + SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}" + + if [ -z "$SL_Key" ]; then + SL_Key="" + _err "You don't specify selectel.ru api key yet." + _err "Please create you key and try again." + return 1 + fi + #save the api key to the account conf file. + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Key "$SL_Key" + fi + elif [ "$SL_Ver" = "v2" ]; then + # time expire token + SL_Expire="${SL_Expire:-$(_readaccountconf_mutable SL_Expire)}" + if [ -z "$SL_Expire" ]; then + SL_Expire=1400 # 23h 20 min + fi + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Expire "$SL_Expire" + fi + # login service user + SL_Login_Name="${SL_Login_Name:-$(_readaccountconf_mutable SL_Login_Name)}" + if [ -z "$SL_Login_Name" ]; then + SL_Login_Name='' + _err "You did not specify the selectel.ru API service user name." + _err "Please provide a service user name and try again." + return 1 + fi + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Login_Name "$SL_Login_Name" + fi + # user ID + SL_Login_ID="${SL_Login_ID:-$(_readaccountconf_mutable SL_Login_ID)}" + if [ -z "$SL_Login_ID" ]; then + SL_Login_ID='' + _err "You did not specify the selectel.ru API user ID." + _err "Please provide a user ID and try again." + return 1 + fi + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Login_ID "$SL_Login_ID" + fi + # project name + SL_Project_Name="${SL_Project_Name:-$(_readaccountconf_mutable SL_Project_Name)}" + if [ -z "$SL_Project_Name" ]; then + SL_Project_Name='' + _err "You did not specify the project name." + _err "Please provide a project name and try again." + return 1 + fi + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Project_Name "$SL_Project_Name" + fi + # service user password + SL_Pswd="${SL_Pswd:-$(_readaccountconf_mutable SL_Pswd)}" + #_secure_debug3 SL_Pswd "$SL_Pswd" + if [ -z "$SL_Pswd" ]; then + SL_Pswd='' + _err "You did not specify the service user password." + _err "Please provide a service user password and try again." + return 1 + fi + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Pswd "$SL_Pswd" "12345678" + fi + else + SL_Ver="" + _err "You also specified the wrong version of the selectel.ru API." + _err "Please provide the correct API version and try again." + return 1 + fi + + if [ -z "$_non_save" ]; then + _saveaccountconf_mutable SL_Ver "$SL_Ver" + fi + + return 0 +} From 577920de863d7ee142cc86f925eca1d1526bf441 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Tue, 30 Apr 2024 08:36:36 +1000 Subject: [PATCH 02/16] test DNS for v2 (actual) 001 --- dnsapi/dns_selectel.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index f5b6b1b9..99f031dd 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -513,6 +513,5 @@ _sl_init_vars() { if [ -z "$_non_save" ]; then _saveaccountconf_mutable SL_Ver "$SL_Ver" fi - return 0 } From 73fe47ba798d269f3082aa4ec5ca06c1f4f6fb1f Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Tue, 30 Apr 2024 09:57:49 +1000 Subject: [PATCH 03/16] test DNS for v1 (legacy) 001 --- dnsapi/dns_selectel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 99f031dd..73210164 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -427,7 +427,7 @@ _sl_init_vars() { # version API SL_Ver="${SL_Ver:-$(_readaccountconf_mutable SL_Ver)}" if [ -z "$SL_Ver" ]; then - SL_Ver="v2" + SL_Ver="v1" fi if ! [ "$SL_Ver" = "v1" ] && ! [ "$SL_Ver" = "v2" ]; then _err "You don't specify selectel.ru API version." From b8949ba3dd82f1846eef195e75700c148a91f214 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Tue, 30 Apr 2024 10:01:50 +1000 Subject: [PATCH 04/16] test DNS for v1 (legacy) 002 --- dnsapi/dns_selectel.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 73210164..04c9a388 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -513,5 +513,6 @@ _sl_init_vars() { if [ -z "$_non_save" ]; then _saveaccountconf_mutable SL_Ver "$SL_Ver" fi + return 0 } From ada7e12b5a85297c42f6169e65612ac0cd2eb709 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Tue, 30 Apr 2024 11:03:53 +1000 Subject: [PATCH 05/16] test DNS for v1 (legacy) 003 --- dnsapi/dns_selectel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 04c9a388..f5b6b1b9 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -427,7 +427,7 @@ _sl_init_vars() { # version API SL_Ver="${SL_Ver:-$(_readaccountconf_mutable SL_Ver)}" if [ -z "$SL_Ver" ]; then - SL_Ver="v1" + SL_Ver="v2" fi if ! [ "$SL_Ver" = "v1" ] && ! [ "$SL_Ver" = "v2" ]; then _err "You don't specify selectel.ru API version." From 2e3c1ef4ac7f0d971f2afe4e18a9b07c5e0427ca Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Tue, 30 Apr 2024 13:49:53 +1000 Subject: [PATCH 06/16] test DNS for v1 (legacy) 003 --- dnsapi/dns_selectel.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index f5b6b1b9..99f031dd 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -513,6 +513,5 @@ _sl_init_vars() { if [ -z "$_non_save" ]; then _saveaccountconf_mutable SL_Ver "$SL_Ver" fi - return 0 } From 8bb29f53d131f4761752a979d03270d650a260f1 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Tue, 30 Apr 2024 16:15:45 +1000 Subject: [PATCH 07/16] test DNS for v1 (legacy) 003 --- dnsapi/dns_selectel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 99f031dd..73210164 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -427,7 +427,7 @@ _sl_init_vars() { # version API SL_Ver="${SL_Ver:-$(_readaccountconf_mutable SL_Ver)}" if [ -z "$SL_Ver" ]; then - SL_Ver="v2" + SL_Ver="v1" fi if ! [ "$SL_Ver" = "v1" ] && ! [ "$SL_Ver" = "v2" ]; then _err "You don't specify selectel.ru API version." From 7a1305c1bb3448ba6573101a0cd9854455b2084d Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Sat, 4 May 2024 19:12:42 +1000 Subject: [PATCH 08/16] fix del record for v1, delete one entry at a time --- dnsapi/dns_selectel.sh | 58 +++++++++--------------------------------- 1 file changed, 12 insertions(+), 46 deletions(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 73210164..4806773d 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -2,7 +2,7 @@ # переменные, которые должны быть определены перед запуском # export SL_Ver="v1" - версия API: 'v2' (actual) или 'v1' (legacy). -# По-умолчанию: v2 +# По-умолчанию: v1 # Если SL_Ver="v1" # export SL_Key="API_KEY" - Токен Selectel (API key) # Посмотреть или создать можно в панели управления в правом верхнем углу откройте меню Профиль и настройки -> Ключи API. @@ -32,7 +32,6 @@ dns_selectel_add() { fulldomain=$1 txtvalue=$2 - #if ! _sl_init_vars; then if ! _sl_init_vars; then return 1 fi @@ -66,7 +65,6 @@ dns_selectel_add() { _ext_srv2="/records/" _data="{\"type\":\"TXT\",\"ttl\":60,\"name\":\"$fulldomain\",\"content\":\"$txtvalue\"}" else - #not valid _err "Error. Unsupported version API $SL_Ver" return 1 fi @@ -83,29 +81,27 @@ dns_selectel_add() { # запись TXT с $fulldomain уже существует if [ "$SL_Ver" = "v2" ]; then # надо добавить к существующей записи еще один content - # # считать записи rrset _debug "Getting txt records" _sl_rest GET "${_ext_uri}" - # Если в данной записи, есть текстовое значение $txtvalue, - # то все хорошо, добавлять ничего не надо и результат успешный + # Уже есть значение $txtvalue, добавлять не надо if _contains "$response" "$txtvalue"; then _info "Added, OK" _info "Txt record ${fulldomain} со значением ${txtvalue} already exists" return 0 fi - # группа \1 - полная запись rrset; группа \2 - значение records:[{"content":"\"v1\""},{"content":"\"v2\""}",...], а именно {"content":"\"v1\""},{"content":"\"v2\""}",... + # группа \1 - полная запись rrset; группа \2 - значение атрибута records, а именно {"content":"\"value1\""},{"content":"\"value2\""}",... _record_seg="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*${fulldomain}[^}]*records[^}]*\[(\{[^]]*\})\][^}]*}).*/\1/p")" _record_array="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*${fulldomain}[^}]*records[^}]*\[(\{[^]]*\})\][^}]*}).*/\2/p")" # record id _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" + # готовим _data _tmp_str="${_record_array},{\"content\":\"${_text_tmp}\"}" _data="{\"ttl\": 60, \"records\": [${_tmp_str}]}" _debug3 _record_seg "$_record_seg" _debug3 _record_array "$_record_array" _debug3 _record_array "$_record_id" - _debug3 _data "$_data" - # вызов REST API PATCH + _debug2 "New data for record" "$_data" if _sl_rest PATCH "${_ext_uri}${_record_id}" "$_data"; then _info "Added, OK" return 0 @@ -124,7 +120,7 @@ dns_selectel_add() { dns_selectel_rm() { fulldomain=$1 txtvalue=$2 - #SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}" + if ! _sl_init_vars "nosave"; then return 1 fi @@ -151,7 +147,6 @@ dns_selectel_rm() { _ext_srv1="/" _ext_srv2="/records/" else - #not valid _err "Error. Unsupported version API $SL_Ver" return 1 fi @@ -169,13 +164,9 @@ dns_selectel_rm() { if [ "$SL_Ver" = "v2" ]; then _record_seg="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\1/gp")" _record_arr="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\3/p")" - #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2)" elif [ "$SL_Ver" = "v1" ]; then _record_seg="$(echo "$response" | _egrep_o "[^{]*\"content\" *: *\"$txtvalue\"[^}]*}")" - # record id - #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2)" else - #not valid _err "Error. Unsupported version API $SL_Ver" return 1 fi @@ -185,7 +176,7 @@ dns_selectel_rm() { return 1 fi # record id - _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" + _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"" | sed '1!d')" if [ -z "$_record_id" ]; then _err "can not find _record_id" return 1 @@ -194,7 +185,6 @@ dns_selectel_rm() { # delete all record type TXT with text $txtvalue if [ "$SL_Ver" = "v2" ]; then # actual - #del_txt='it47Qq60vJuzQJXb9WEaapciTwtt1gb_14gm1ubwzrA'; _new_arr="$(echo "$_record_seg" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\3/gp" | sed -En "s/(\},\{)/}\n{/gp" | sed "/${txtvalue}/d" | sed ":a;N;s/\n/,/;ta")" # uri record for DEL or PATCH _del_uri="${_ext_uri}${_record_id}" @@ -232,14 +222,10 @@ dns_selectel_rm() { } #################### Private functions below ################################## -#_acme-challenge.www.domain.com -#returns -# _sub_domain=_acme-challenge.www -# _domain=domain.com -# _domain_id=sdjkglgdfewsdfg + _get_root() { domain=$1 - # + if [ "$SL_Ver" = 'v1' ]; then # version API 1 if ! _sl_rest GET "/"; then @@ -248,16 +234,12 @@ _get_root() { i=2 p=1 while true; do - #h=$(printf "%s" "$domain" | cut -d . -f $i-100) h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then - #not valid return 1 fi - if _contains "$response" "\"name\" *: *\"$h\","; then - #_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h _debug "Getting domain id for $h" @@ -280,7 +262,6 @@ _get_root() { _debug "domain:: " "$domain" # read records of all domains if ! _sl_rest GET "$_ext_uri"; then - #not valid _err "Error read records of all domains $SL_Ver" return 1 fi @@ -290,29 +271,24 @@ _get_root() { h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) _debug h "$h" if [ -z "$h" ]; then - #not valid _err "The domain was not found among the registered ones" return 1 fi - _domain_record=$(echo "$response" | sed -En "s/.*(\{[^}]*id[^}]*\"name\" *: *\"$h\"[^}]*}).*/\1/p") _debug "_domain_record:: " "$_domain_record" if [ -n "$_domain_record" ]; then _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p") _domain=$h _debug "Getting domain id for $h" - #_domain_id="$(echo "$_domain_record" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\":" | cut -d : -f 2 | sed -En "s/\"([^\"]*)\"/\1\p")" _domain_id=$(echo "$_domain_record" | sed -En "s/\{[^}]*\"id\" *: *\"([^\"]*)\"[^}]*\}/\1/p") return 0 fi p=$i i=$(_math "$i" + 1) done - #not valid _err "Error read records of all domains $SL_Ver" return 1 else - #not valid _err "Error. Unsupported version API $SL_Ver" return 1 fi @@ -341,14 +317,12 @@ _sl_rest() { _debug3 "Full URI: " "$SL_Api/${SL_Ver}${ep}" _debug3 "_H1:" "$_H1" _debug3 "_H2:" "$_H2" - if [ "$m" != "GET" ]; then _debug data "$data" response="$(_post "$data" "$SL_Api/${SL_Ver}${ep}" "" "$m")" else response="$(_get "$SL_Api/${SL_Ver}${ep}")" fi - if [ "$?" != "0" ]; then _err "error $ep" return 1 @@ -357,8 +331,6 @@ _sl_rest() { return 0 } -#################################################################3 -# use: _get_auth_token() { if [ "$SL_Ver" = 'v1' ]; then # token for v1 @@ -375,7 +347,7 @@ _get_auth_token() { # field 3 - SL_Login_ID # field 4 - SL_Project_Name # field 5 - Receipt time - # separator - ';' + # separator - '$_sl_sep' _login_name=$(_getfield "$token_v2" 1 "$_sl_sep") _token_keystone=$(_getfield "$token_v2" 2 "$_sl_sep") _project_name=$(_getfield "$token_v2" 4 "$_sl_sep") @@ -386,7 +358,6 @@ _get_auth_token() { _debug3 _project_name "$_project_name" _debug3 _receipt_time "$(date -d @"$_receipt_time" -u)" # check the validity of the token for the user and the project and its lifetime - #_dt_diff_minute=$(( ( $(EPOCHSECONDS)-$_receipt_time )/60 )) _dt_diff_minute=$((($(date +%s) - _receipt_time) / 60)) _debug3 _dt_diff_minute "$_dt_diff_minute" [ "$_dt_diff_minute" -gt "$SL_Expire" ] && unset _token_keystone @@ -399,13 +370,9 @@ _get_auth_token() { # the previous token is incorrect or was not received, get a new one _debug "Update (get new) token" _data_auth="{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":{\"user\":{\"name\":\"${SL_Login_Name}\",\"domain\":{\"name\":\"${SL_Login_ID}\"},\"password\":\"${SL_Pswd}\"}}},\"scope\":{\"project\":{\"name\":\"${SL_Project_Name}\",\"domain\":{\"name\":\"${SL_Login_ID}\"}}}}}" - #_secure_debug2 "_data_auth" "$_data_auth" export _H1="Content-Type: application/json" - # body url [needbase64] [POST|PUT|DELETE] [ContentType] _result=$(_post "$_data_auth" "$auth_uri") _token_keystone=$(grep 'x-subject-token' "$HTTP_HEADER" | sed -nE "s/[[:space:]]*x-subject-token:[[:space:]]*([[:print:]]*)(\r*)/\1/p") - #echo $_token_keystone > /root/123456.qwe - #_dt_curr=$EPOCHSECONDS _dt_curr=$(date +%s) SL_Token_V2="${SL_Login_Name}${_sl_sep}${_token_keystone}${_sl_sep}${SL_Login_ID}${_sl_sep}${SL_Project_Name}${_sl_sep}${_dt_curr}" _saveaccountconf_mutable SL_Token_V2 "$SL_Token_V2" @@ -427,14 +394,13 @@ _sl_init_vars() { # version API SL_Ver="${SL_Ver:-$(_readaccountconf_mutable SL_Ver)}" if [ -z "$SL_Ver" ]; then - SL_Ver="v1" + SL_Ver="v2" fi if ! [ "$SL_Ver" = "v1" ] && ! [ "$SL_Ver" = "v2" ]; then _err "You don't specify selectel.ru API version." _err "Please define specify API version." fi _debug2 SL_Ver "$SL_Ver" - if [ "$SL_Ver" = "v1" ]; then # token SL_Key="${SL_Key:-$(_readaccountconf_mutable SL_Key)}" @@ -509,9 +475,9 @@ _sl_init_vars() { _err "Please provide the correct API version and try again." return 1 fi - if [ -z "$_non_save" ]; then _saveaccountconf_mutable SL_Ver "$SL_Ver" fi + return 0 } From 177d9b7cb0fce9baabbc5fa90aa86f8765e33c3b Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Sat, 4 May 2024 20:38:42 +1000 Subject: [PATCH 09/16] set default SL_Ver to v1 --- dnsapi/dns_selectel.sh | 47 +++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 4806773d..65729804 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -4,7 +4,7 @@ # export SL_Ver="v1" - версия API: 'v2' (actual) или 'v1' (legacy). # По-умолчанию: v1 # Если SL_Ver="v1" -# export SL_Key="API_KEY" - Токен Selectel (API key) +# export SL_Key="API_Key" - Токен Selectel (API key) # Посмотреть или создать можно в панели управления в правом верхнем углу откройте меню Профиль и настройки -> Ключи API. # https://my.selectel.ru/profile/apikeys # Если SL_Ver="v2" @@ -35,12 +35,11 @@ dns_selectel_add() { if ! _sl_init_vars; then return 1 fi - _debug2 SL_Ver "$SL_Ver" - _secure_debug3 SL_Key "$SL_Key" - _debug2 SL_Expire "$SL_Expire" - _debug2 SL_Login_Name "$SL_Login_Name" - _debug2 SL_Login_ID "$SL_Login_ID" - _debug2 SL_Project_Name "$SL_Project_Name" + _debug3 SL_Ver "$SL_Ver" + _debug3 SL_Expire "$SL_Expire" + _debug3 SL_Login_Name "$SL_Login_Name" + _debug3 SL_Login_ID "$SL_Login_ID" + _debug3 SL_Project_Name "$SL_Project_Name" _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -56,9 +55,7 @@ dns_selectel_add() { _ext_srv1="/zones/" _ext_srv2="/rrset/" _text_tmp=$(echo "$txtvalue" | sed -En "s/[\"]*([^\"]*)/\1/p") - _debug txtvalue "$txtvalue" _text_tmp='\"'$_text_tmp'\"' - _debug _text_tmp "$_text_tmp" _data="{\"type\": \"TXT\", \"ttl\": 60, \"name\": \"${fulldomain}.\", \"records\": [{\"content\":\"$_text_tmp\"}]}" elif [ "$SL_Ver" = "v1" ]; then _ext_srv1="/" @@ -69,8 +66,8 @@ dns_selectel_add() { return 1 fi _ext_uri="${_ext_srv1}$_domain_id${_ext_srv2}" - _debug3 _ext_uri "$_ext_uri" - _debug3 _data "$_data" + _debug _ext_uri "$_ext_uri" + _debug _data "$_data" if _sl_rest POST "$_ext_uri" "$_data"; then if _contains "$response" "$txtvalue"; then @@ -101,7 +98,7 @@ dns_selectel_add() { _debug3 _record_seg "$_record_seg" _debug3 _record_array "$_record_array" _debug3 _record_array "$_record_id" - _debug2 "New data for record" "$_data" + _debug "New data for record" "$_data" if _sl_rest PATCH "${_ext_uri}${_record_id}" "$_data"; then _info "Added, OK" return 0 @@ -124,12 +121,11 @@ dns_selectel_rm() { if ! _sl_init_vars "nosave"; then return 1 fi - _debug2 SL_Ver "$SL_Ver" - _secure_debug3 SL_Key "$SL_Key" - _debug2 SL_Expire "$SL_Expire" - _debug2 SL_Login_Name "$SL_Login_Name" - _debug2 SL_Login_ID "$SL_Login_ID" - _debug2 SL_Project_Name "$SL_Project_Name" + _debug3 SL_Ver "$SL_Ver" + _debug3 SL_Expire "$SL_Expire" + _debug3 SL_Login_Name "$SL_Login_Name" + _debug3 SL_Login_ID "$SL_Login_ID" + _debug3 SL_Project_Name "$SL_Project_Name" # _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -153,7 +149,7 @@ dns_selectel_rm() { # _debug "Getting txt records" _ext_uri="${_ext_srv1}$_domain_id${_ext_srv2}" - _debug3 _ext_uri "$_ext_uri" + _debug _ext_uri "$_ext_uri" _sl_rest GET "${_ext_uri}" # if ! _contains "$response" "$txtvalue"; then @@ -176,7 +172,11 @@ dns_selectel_rm() { return 1 fi # record id - _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"" | sed '1!d')" + # следующие строки меняют алгоритм удаления записей со значением $txtvalue + # если использовать 1-ю строку, то за раз удаляются все такие записи + # если использовать 2-ю строку, то удаляется только первая запись из них + #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" # удалять все записи со значением $txtvalue + _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"" | sed '1!d')" # удалять только первую запись со значением $txtvalue if [ -z "$_record_id" ]; then _err "can not find _record_id" return 1 @@ -188,6 +188,7 @@ dns_selectel_rm() { _new_arr="$(echo "$_record_seg" | sed -En "s/.*(\{\"id\"[^}]*records[^[]*(\[(\{[^]]*${txtvalue}[^]]*)\])[^}]*}).*/\3/gp" | sed -En "s/(\},\{)/}\n{/gp" | sed "/${txtvalue}/d" | sed ":a;N;s/\n/,/;ta")" # uri record for DEL or PATCH _del_uri="${_ext_uri}${_record_id}" + _debug _del_uri "$_del_uri" if [ -z "$_new_arr" ]; then # удалить запись if ! _sl_rest DELETE "${_del_uri}"; then @@ -210,7 +211,7 @@ dns_selectel_rm() { # legacy for _one_id in $_record_id; do _del_uri="${_ext_uri}${_one_id}" - _debug2 _ext_uri "$_del_uri" + _debug _del_uri "$_del_uri" if ! _sl_rest DELETE "${_del_uri}"; then _err "Delete record error: ${_del_uri}." else @@ -302,7 +303,6 @@ _sl_rest() { data="$3" _token=$(_get_auth_token) - #_debug "$_token" if [ -z "$_token" ]; then _err "BAD key or token $ep" return 1 @@ -394,7 +394,7 @@ _sl_init_vars() { # version API SL_Ver="${SL_Ver:-$(_readaccountconf_mutable SL_Ver)}" if [ -z "$SL_Ver" ]; then - SL_Ver="v2" + SL_Ver="v1" fi if ! [ "$SL_Ver" = "v1" ] && ! [ "$SL_Ver" = "v2" ]; then _err "You don't specify selectel.ru API version." @@ -459,7 +459,6 @@ _sl_init_vars() { fi # service user password SL_Pswd="${SL_Pswd:-$(_readaccountconf_mutable SL_Pswd)}" - #_secure_debug3 SL_Pswd "$SL_Pswd" if [ -z "$SL_Pswd" ]; then SL_Pswd='' _err "You did not specify the service user password." From d989617825ccc0b9a60b4f9f657148243d14b15b Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Sat, 4 May 2024 20:42:38 +1000 Subject: [PATCH 10/16] set default SL_Ver to v1 --- dnsapi/dns_selectel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 65729804..9868cb12 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -173,7 +173,7 @@ dns_selectel_rm() { fi # record id # следующие строки меняют алгоритм удаления записей со значением $txtvalue - # если использовать 1-ю строку, то за раз удаляются все такие записи + # если использовать 1-ю строку, то за раз удаляются все такие записи # если использовать 2-ю строку, то удаляется только первая запись из них #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" # удалять все записи со значением $txtvalue _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"" | sed '1!d')" # удалять только первую запись со значением $txtvalue From a375e924b491e8245ee763305f59627eac996f80 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mai.ru> Date: Sun, 5 May 2024 07:42:22 +1000 Subject: [PATCH 11/16] translation of comments into English --- dnsapi/dns_selectel.sh | 62 +++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 9868cb12..d4ca13b2 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -1,23 +1,23 @@ #!/usr/bin/env sh -# переменные, которые должны быть определены перед запуском -# export SL_Ver="v1" - версия API: 'v2' (actual) или 'v1' (legacy). -# По-умолчанию: v1 -# Если SL_Ver="v1" -# export SL_Key="API_Key" - Токен Selectel (API key) -# Посмотреть или создать можно в панели управления в правом верхнем углу откройте меню Профиль и настройки -> Ключи API. +# Variables that must be defined before running +# export SL_Ver="v1" - version API: 'v2' (actual) or 'v1' (legacy). +# Default: v1 +# If SL_Ver="v1" +# export SL_Key="API_Key" - Token Selectel (API key) +# You can view or create in the control panel in the upper right corner, open the menu: "Profile and setting -> Keys API". # https://my.selectel.ru/profile/apikeys -# Если SL_Ver="v2" -# export SL_Expire=60 - время жизни token в минутах (0-1440). -# По-умолчанию: 1400 минут -# export SL_Login_ID= - номер аккаунта в панели управления; -# export SL_Project_Name= - имя проекта. -# export SL_Login_name= - имя сервисного пользователя. Посмотреть имя можно в панели управления: -# в правом верхнем углу откройте меню → Профиль и настройки → раздел Управление пользователями → вкладка Сервисные пользователи -# export SL_Pswd='pswd' - пароль сервисного пользователя, можно посмотреть при создании пользователя или изменить на новый. -# Все эти переменные будут сохранены ~/.acme.sh/account.conf и будут использоваться повторно при необходимости. +# If SL_Ver="v2" +# export SL_Expire=60 - token lifetime in minutes (0-1440). +# Default: 1400 minutes +# export SL_Login_ID= - account number in the control panel; +# export SL_Project_Name= - name project. +# export SL_Login_name= - service user name. You can view the name in the control panel: +# in the upper right corner open menu: "Profile and setting → User management → Service users +# export SL_Pswd='pswd' - service user password, can be viewed when creating a user or changed to a new one. +# All these variables will be saved in ~/.acme.sh/account.conf and will be reused as needed. # -# Авторизация описана в: +# Authorization is described in: # https://developers.selectel.ru/docs/control-panel/authorization/ # https://developers.selectel.com/docs/control-panel/authorization/ @@ -75,24 +75,24 @@ dns_selectel_add() { return 0 fi if _contains "$response" "already_exists"; then - # запись TXT с $fulldomain уже существует + # record TXT with $fulldomain already exists if [ "$SL_Ver" = "v2" ]; then - # надо добавить к существующей записи еще один content - # считать записи rrset + # It is necessary to add one more content to the comments + # read all records rrset _debug "Getting txt records" _sl_rest GET "${_ext_uri}" - # Уже есть значение $txtvalue, добавлять не надо + # There is already a $txtvalue value, no need to add it if _contains "$response" "$txtvalue"; then _info "Added, OK" - _info "Txt record ${fulldomain} со значением ${txtvalue} already exists" + _info "Txt record ${fulldomain} with value ${txtvalue} already exists" return 0 fi - # группа \1 - полная запись rrset; группа \2 - значение атрибута records, а именно {"content":"\"value1\""},{"content":"\"value2\""}",... + # group \1 - full record rrset; group \2 - records attribute value, exactly {"content":"\"value1\""},{"content":"\"value2\""}",... _record_seg="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*${fulldomain}[^}]*records[^}]*\[(\{[^]]*\})\][^}]*}).*/\1/p")" _record_array="$(echo "$response" | sed -En "s/.*(\{\"id\"[^}]*${fulldomain}[^}]*records[^}]*\[(\{[^]]*\})\][^}]*}).*/\2/p")" # record id _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" - # готовим _data + # preparing _data _tmp_str="${_record_array},{\"content\":\"${_text_tmp}\"}" _data="{\"ttl\": 60, \"records\": [${_tmp_str}]}" _debug3 _record_seg "$_record_seg" @@ -172,11 +172,11 @@ dns_selectel_rm() { return 1 fi # record id - # следующие строки меняют алгоритм удаления записей со значением $txtvalue - # если использовать 1-ю строку, то за раз удаляются все такие записи - # если использовать 2-ю строку, то удаляется только первая запись из них - #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" # удалять все записи со значением $txtvalue - _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"" | sed '1!d')" # удалять только первую запись со значением $txtvalue + # the following lines change the algorithm for deleting records with the value $txtvalue + # if you use the 1st line, then all such records are deleted at once + # if you use the 2nd line, then only the first entry from them is deleted + #_record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"")" + _record_id="$(echo "$_record_seg" | tr "," "\n" | tr "}" "\n" | tr -d " " | grep "\"id\"" | cut -d : -f 2 | tr -d "\"" | sed '1!d')" if [ -z "$_record_id" ]; then _err "can not find _record_id" return 1 @@ -190,17 +190,17 @@ dns_selectel_rm() { _del_uri="${_ext_uri}${_record_id}" _debug _del_uri "$_del_uri" if [ -z "$_new_arr" ]; then - # удалить запись + # remove record if ! _sl_rest DELETE "${_del_uri}"; then _err "Delete record error: ${_del_uri}." else info "Delete record success: ${_del_uri}." fi else - # обновить запись, удалив content + # update a record by removing one element in content _data="{\"ttl\": 60, \"records\": [${_new_arr}]}" _debug3 _data "$_data" - # вызов REST API PATCH + # REST API PATCH call if _sl_rest PATCH "${_del_uri}" "$_data"; then _info "Patched, OK: ${_del_uri}" else From 51151293d7556dde713c197d0fdc83b97cbbe642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=BB=D0=B0=D0=B4=D0=B8=D0=BC=D0=B8=D1=80=20=D0=90?= =?UTF-8?q?=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B5=D0=B2?= <73811032+vlad-kms@users.noreply.github.com> Date: Sat, 6 Jul 2024 21:01:25 +1000 Subject: [PATCH 12/16] Remove `date -d` on macOS --- dnsapi/dns_selectel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index c8aa2db7..511ab7f5 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -356,7 +356,7 @@ _get_auth_token() { _debug3 _login_name "$_login_name" _debug3 _login_id "$_login_id" _debug3 _project_name "$_project_name" - _debug3 _receipt_time "$(date -d @"$_receipt_time" -u)" + # _debug3 _receipt_time "$(date -d @"$_receipt_time" -u)" # check the validity of the token for the user and the project and its lifetime _dt_diff_minute=$((($(date +%s) - _receipt_time) / 60)) _debug3 _dt_diff_minute "$_dt_diff_minute" From e42ad9be242dadc565ab7d93fc96b63519101563 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mail.ru> Date: Mon, 23 Dec 2024 14:50:28 +1000 Subject: [PATCH 13/16] fix don't use debug3, use debug2 add # shellcheck disable=SC2034 --- dnsapi/dns_selectel.sh | 49 +++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 511ab7f5..7782fa44 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -1,4 +1,5 @@ #!/usr/bin/env sh +# shellcheck disable=SC2034 # Variables that must be defined before running # export SL_Ver="v1" - version API: 'v2' (actual) or 'v1' (legacy). @@ -35,11 +36,11 @@ dns_selectel_add() { if ! _sl_init_vars; then return 1 fi - _debug3 SL_Ver "$SL_Ver" - _debug3 SL_Expire "$SL_Expire" - _debug3 SL_Login_Name "$SL_Login_Name" - _debug3 SL_Login_ID "$SL_Login_ID" - _debug3 SL_Project_Name "$SL_Project_Name" + _debug2 SL_Ver "$SL_Ver" + _debug2 SL_Expire "$SL_Expire" + _debug2 SL_Login_Name "$SL_Login_Name" + _debug2 SL_Login_ID "$SL_Login_ID" + _debug2 SL_Project_Name "$SL_Project_Name" _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -95,9 +96,9 @@ dns_selectel_add() { # preparing _data _tmp_str="${_record_array},{\"content\":\"${_text_tmp}\"}" _data="{\"ttl\": 60, \"records\": [${_tmp_str}]}" - _debug3 _record_seg "$_record_seg" - _debug3 _record_array "$_record_array" - _debug3 _record_array "$_record_id" + _debug2 _record_seg "$_record_seg" + _debug2 _record_array "$_record_array" + _debug2 _record_array "$_record_id" _debug "New data for record" "$_data" if _sl_rest PATCH "${_ext_uri}${_record_id}" "$_data"; then _info "Added, OK" @@ -121,11 +122,11 @@ dns_selectel_rm() { if ! _sl_init_vars "nosave"; then return 1 fi - _debug3 SL_Ver "$SL_Ver" - _debug3 SL_Expire "$SL_Expire" - _debug3 SL_Login_Name "$SL_Login_Name" - _debug3 SL_Login_ID "$SL_Login_ID" - _debug3 SL_Project_Name "$SL_Project_Name" + _debug2 SL_Ver "$SL_Ver" + _debug2 SL_Expire "$SL_Expire" + _debug2 SL_Login_Name "$SL_Login_Name" + _debug2 SL_Login_ID "$SL_Login_ID" + _debug2 SL_Project_Name "$SL_Project_Name" # _debug "First detect the root zone" if ! _get_root "$fulldomain"; then @@ -166,7 +167,7 @@ dns_selectel_rm() { _err "Error. Unsupported version API $SL_Ver" return 1 fi - _debug3 "_record_seg" "$_record_seg" + _debug2 "_record_seg" "$_record_seg" if [ -z "$_record_seg" ]; then _err "can not find _record_seg" return 1 @@ -181,7 +182,7 @@ dns_selectel_rm() { _err "can not find _record_id" return 1 fi - _debug3 "_record_id" "$_record_id" + _debug2 "_record_id" "$_record_id" # delete all record type TXT with text $txtvalue if [ "$SL_Ver" = "v2" ]; then # actual @@ -199,7 +200,7 @@ dns_selectel_rm() { else # update a record by removing one element in content _data="{\"ttl\": 60, \"records\": [${_new_arr}]}" - _debug3 _data "$_data" + _debug2 _data "$_data" # REST API PATCH call if _sl_rest PATCH "${_del_uri}" "$_data"; then _info "Patched, OK: ${_del_uri}" @@ -314,15 +315,16 @@ _sl_rest() { fi export _H1="${_h1_name}: ${_token}" export _H2="Content-Type: application/json" - _debug3 "Full URI: " "$SL_Api/${SL_Ver}${ep}" - _debug3 "_H1:" "$_H1" - _debug3 "_H2:" "$_H2" + _debug2 "Full URI: " "$SL_Api/${SL_Ver}${ep}" + _debug2 "_H1:" "$_H1" + _debug2 "_H2:" "$_H2" if [ "$m" != "GET" ]; then _debug data "$data" response="$(_post "$data" "$SL_Api/${SL_Ver}${ep}" "" "$m")" else response="$(_get "$SL_Api/${SL_Ver}${ep}")" fi + # shellcheck disable=SC2181 if [ "$?" != "0" ]; then _err "error $ep" return 1 @@ -353,13 +355,12 @@ _get_auth_token() { _project_name=$(_getfield "$token_v2" 4 "$_sl_sep") _receipt_time=$(_getfield "$token_v2" 5 "$_sl_sep") _login_id=$(_getfield "$token_v2" 3 "$_sl_sep") - _debug3 _login_name "$_login_name" - _debug3 _login_id "$_login_id" - _debug3 _project_name "$_project_name" - # _debug3 _receipt_time "$(date -d @"$_receipt_time" -u)" + _debug2 _login_name "$_login_name" + _debug2 _login_id "$_login_id" + _debug2 _project_name "$_project_name" # check the validity of the token for the user and the project and its lifetime _dt_diff_minute=$((($(date +%s) - _receipt_time) / 60)) - _debug3 _dt_diff_minute "$_dt_diff_minute" + _debug2 _dt_diff_minute "$_dt_diff_minute" [ "$_dt_diff_minute" -gt "$SL_Expire" ] && unset _token_keystone if [ "$_project_name" != "$SL_Project_Name" ] || [ "$_login_name" != "$SL_Login_Name" ] || [ "$_login_id" != "$SL_Login_ID" ]; then unset _token_keystone From 112bfccfd52f05db43f68946c9047399a541bfc5 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mail.ru> Date: Tue, 24 Dec 2024 16:00:01 +1000 Subject: [PATCH 14/16] fix _get_root() make it start from 1. because we need to support --domain-alias (only version api actual v2) --- dnsapi/dns_selectel.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 7782fa44..309c6b17 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -267,7 +267,7 @@ _get_root() { _err "Error read records of all domains $SL_Ver" return 1 fi - i=2 + i=1 p=1 while true; do h=$(printf "%s" "$domain" | cut -d . -f "$i"-100) From 3f262fe872071c2fdc37c0528380e7f9d17ce669 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mail.ru> Date: Thu, 26 Dec 2024 08:12:36 +1000 Subject: [PATCH 15/16] keep content: # dns_selectel_info='Selectel.com # Domains: Selectel.ru # Site: Selectel.com # Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_selectel # Options: # Variables that must be defined before running --- dnsapi/dns_selectel.sh | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 309c6b17..1e1a769a 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -1,26 +1,28 @@ #!/usr/bin/env sh # shellcheck disable=SC2034 +# dns_selectel_info='Selectel.com +# Domains: Selectel.ru +# Site: Selectel.com +# Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_selectel +# Options: # Variables that must be defined before running -# export SL_Ver="v1" - version API: 'v2' (actual) or 'v1' (legacy). -# Default: v1 -# If SL_Ver="v1" -# export SL_Key="API_Key" - Token Selectel (API key) -# You can view or create in the control panel in the upper right corner, open the menu: "Profile and setting -> Keys API". -# https://my.selectel.ru/profile/apikeys -# If SL_Ver="v2" -# export SL_Expire=60 - token lifetime in minutes (0-1440). -# Default: 1400 minutes -# export SL_Login_ID= - account number in the control panel; -# export SL_Project_Name= - name project. -# export SL_Login_Name= - service user name. You can view the name in the control panel: -# in the upper right corner open menu: "Profile and setting → User management → Service users -# export SL_Pswd='pswd' - service user password, can be viewed when creating a user or changed to a new one. -# All these variables will be saved in ~/.acme.sh/account.conf and will be reused as needed. +# SL_Ver='v1', when using version API legacy (v1) +# OR +# SL_Ver='v2', when using version API actual (v2) +# default = 'v1' +# when using API version v1, i.e. SL_Ver is 'v1' or not defined: +# SL_Key - API Key, required +# when using API version v2: +# SL_Ver - required as 'v2' +# SL_Login_ID - account ID, required +# SL_Project_Name - name project, required +# SL_Login_Name - service user name, required +# SL_Pswd - service user password, required +# SL_Expire - token lifetime in minutes (0-1440), default 1400 minutes +# +# Issues: github.com/acmesh-official/acme.sh/issues/5126 # -# Authorization is described in: -# https://developers.selectel.ru/docs/control-panel/authorization/ -# https://developers.selectel.com/docs/control-panel/authorization/ SL_Api="https://api.selectel.ru/domains" auth_uri="https://cloud.api.selcloud.ru/identity/v3/auth/tokens" From d3f3a703507fdc8d9733baea846420bcbe3558e5 Mon Sep 17 00:00:00 2001 From: Vladimir Alexeev <9141778236@mail.ru> Date: Thu, 26 Dec 2024 08:45:03 +1000 Subject: [PATCH 16/16] keep content: # dns_selectel_info='Selectel.com # Domains: Selectel.ru # Site: Selectel.com # Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_selectel # Options: # Variables that must be defined before running --- dnsapi/dns_selectel.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dnsapi/dns_selectel.sh b/dnsapi/dns_selectel.sh index 1e1a769a..434bc483 100644 --- a/dnsapi/dns_selectel.sh +++ b/dnsapi/dns_selectel.sh @@ -7,10 +7,9 @@ # Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_selectel # Options: # Variables that must be defined before running +# SL_Ver can take one of the values 'v1' or 'v2', default is 'v1' # SL_Ver='v1', when using version API legacy (v1) -# OR # SL_Ver='v2', when using version API actual (v2) -# default = 'v1' # when using API version v1, i.e. SL_Ver is 'v1' or not defined: # SL_Key - API Key, required # when using API version v2: