Hunter0x7c7
2022-08-11 f32244833adb9f9d8323c773559d20865c2c7411
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#!/usr/bin/env sh
 
# DNSimple domain api
# https://github.com/pho3nixf1re/acme.sh/issues
#
# This is your oauth token which can be acquired on the account page. Please
# note that this must be an _account_ token and not a _user_ token.
# https://dnsimple.com/a/<your account id>/account/access_tokens
# DNSimple_OAUTH_TOKEN="sdfsdfsdfljlbjkljlkjsdfoiwje"
 
DNSimple_API="https://api.dnsimple.com/v2"
 
########  Public functions #####################
 
# Usage: add  _acme-challenge.www.domain.com   "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_dnsimple_add() {
  fulldomain=$1
  txtvalue=$2
 
  if [ -z "$DNSimple_OAUTH_TOKEN" ]; then
    DNSimple_OAUTH_TOKEN=""
    _err "You have not set the dnsimple oauth token yet."
    _err "Please visit https://dnsimple.com/user to generate it."
    return 1
  fi
 
  # save the oauth token for later
  _saveaccountconf DNSimple_OAUTH_TOKEN "$DNSimple_OAUTH_TOKEN"
 
  if ! _get_account_id; then
    _err "failed to retrive account id"
    return 1
  fi
 
  if ! _get_root "$fulldomain"; then
    _err "invalid domain"
    return 1
  fi
 
  _get_records "$_account_id" "$_domain" "$_sub_domain"
 
  _info "Adding record"
  if _dnsimple_rest POST "$_account_id/zones/$_domain/records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then
    if printf -- "%s" "$response" | grep "\"name\":\"$_sub_domain\"" >/dev/null; then
      _info "Added"
      return 0
    else
      _err "Unexpected response while adding text record."
      return 1
    fi
  fi
  _err "Add txt record error."
}
 
# fulldomain
dns_dnsimple_rm() {
  fulldomain=$1
 
  if ! _get_account_id; then
    _err "failed to retrive account id"
    return 1
  fi
 
  if ! _get_root "$fulldomain"; then
    _err "invalid domain"
    return 1
  fi
 
  _get_records "$_account_id" "$_domain" "$_sub_domain"
 
  _extract_record_id "$_records" "$_sub_domain"
  if [ "$_record_id" ]; then
    echo "$_record_id" | while read -r item; do
      if _dnsimple_rest DELETE "$_account_id/zones/$_domain/records/$item"; then
        _info "removed record" "$item"
        return 0
      else
        _err "failed to remove record" "$item"
        return 1
      fi
    done
  fi
}
 
####################  Private functions bellow ##################################
# _acme-challenge.www.domain.com
# returns
#   _sub_domain=_acme-challenge.www
#   _domain=domain.com
_get_root() {
  domain=$1
  i=2
  previous=1
  while true; do
    h=$(printf "%s" "$domain" | cut -d . -f $i-100)
    if [ -z "$h" ]; then
      # not valid
      return 1
    fi
 
    if ! _dnsimple_rest GET "$_account_id/zones/$h"; then
      return 1
    fi
 
    if _contains "$response" 'not found'; then
      _debug "$h not found"
    else
      _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$previous)
      _domain="$h"
 
      _debug _domain "$_domain"
      _debug _sub_domain "$_sub_domain"
 
      return 0
    fi
 
    previous="$i"
    i=$(_math "$i" + 1)
  done
  return 1
}
 
# returns _account_id
_get_account_id() {
  _debug "retrive account id"
  if ! _dnsimple_rest GET "whoami"; then
    return 1
  fi
 
  if _contains "$response" "\"account\":null"; then
    _err "no account associated with this token"
    return 1
  fi
 
  if _contains "$response" "timeout"; then
    _err "timeout retrieving account id"
    return 1
  fi
 
  _account_id=$(printf "%s" "$response" | _egrep_o "\"id\":[^,]*,\"email\":" | cut -d: -f2 | cut -d, -f1)
  _debug _account_id "$_account_id"
 
  return 0
}
 
# returns
#   _records
#   _records_count
_get_records() {
  account_id=$1
  domain=$2
  sub_domain=$3
 
  _debug "fetching txt records"
  _dnsimple_rest GET "$account_id/zones/$domain/records?per_page=5000&sort=id:desc"
 
  if ! _contains "$response" "\"id\":"; then
    _err "failed to retrieve records"
    return 1
  fi
 
  _records_count=$(printf "%s" "$response" | _egrep_o "\"name\":\"$sub_domain\"" | wc -l | _egrep_o "[0-9]+")
  _records=$response
  _debug _records_count "$_records_count"
}
 
# returns _record_id
_extract_record_id() {
  _record_id=$(printf "%s" "$_records" | _egrep_o "\"id\":[^,]*,\"zone_id\":\"[^,]*\",\"parent_id\":null,\"name\":\"$_sub_domain\"" | cut -d: -f2 | cut -d, -f1)
  _debug "_record_id" "$_record_id"
}
 
# returns response
_dnsimple_rest() {
  method=$1
  path="$2"
  data="$3"
  request_url="$DNSimple_API/$path"
  _debug "$path"
 
  export _H1="Accept: application/json"
  export _H2="Authorization: Bearer $DNSimple_OAUTH_TOKEN"
 
  if [ "$data" ] || [ "$method" = "DELETE" ]; then
    _H1="Content-Type: application/json"
    _debug data "$data"
    response="$(_post "$data" "$request_url" "" "$method")"
  else
    response="$(_get "$request_url" "" "" "$method")"
  fi
 
  if [ "$?" != "0" ]; then
    _err "error $request_url"
    return 1
  fi
  _debug2 response "$response"
  return 0
}