Merge pull request #3092 from acmesh-official/dev

sync
This commit is contained in:
neil 2020-08-07 12:10:35 +08:00 committed by GitHub
commit 5e6ee5fd48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 796 additions and 24 deletions

View File

@ -1,5 +1,5 @@
language: shell
dist: trusty
dist: bionic
os:
- linux

View File

@ -1,6 +1,8 @@
# An ACME Shell script: acme.sh [![Build Status](https://travis-ci.org/acmesh-official/acme.sh.svg?branch=master)](https://travis-ci.org/acmesh-official/acme.sh)
<a href="https://opencollective.com/acmesh" alt="Financial Contributors on Open Collective"><img src="https://opencollective.com/acmesh/all/badge.svg?label=financial+contributors" /></a> [![Join the chat at https://gitter.im/acme-sh/Lobby](https://badges.gitter.im/acme-sh/Lobby.svg)](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Docker stars](https://img.shields.io/docker/stars/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub")
[![Docker pulls](https://img.shields.io/docker/pulls/neilpang/acme.sh.svg)](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub")
acme.sh is being sponsored by the following tool; please help to support us by taking a look and signing up to a free trial
@ -309,7 +311,7 @@ https://github.com/acmesh-official/acme.sh/wiki/dnsapi
See: https://github.com/acmesh-official/acme.sh/wiki/dns-manual-mode first.
If your dns provider doesn't support any api access, you can add the txt record by your hand.
If your dns provider doesn't support any api access, you can add the txt record by hand.
```bash
acme.sh --issue --dns -d example.com -d www.example.com -d cp.example.com

View File

@ -5642,7 +5642,7 @@ _deactivate() {
_URL_NAME="uri"
fi
entries="$(echo "$response" | _egrep_o "{ *\"type\":\"[^\"]*\", *\"status\": *\"valid\", *\"$_URL_NAME\"[^}]*")"
entries="$(echo "$response" | _egrep_o "[^{]*\"type\":\"[^\"]*\", *\"status\": *\"valid\", *\"$_URL_NAME\"[^}]*")"
if [ -z "$entries" ]; then
_info "No valid entries found."
if [ -z "$thumbprint" ]; then
@ -6448,10 +6448,10 @@ _checkSudo() {
#it's root using sudo, no matter it's using sudo or not, just fine
return 0
fi
if [ "$SUDO_COMMAND" = "/bin/su" ] || [ "$SUDO_COMMAND" = "/bin/bash" ]; then
if [ -n "$SUDO_COMMAND" ]; then
#it's a normal user doing "sudo su", or `sudo -i` or `sudo -s`
#fine
return 0
_endswith "$SUDO_COMMAND" /bin/su || grep "^$SUDO_COMMAND\$" /etc/shells >/dev/null 2>&1
return $?
fi
#otherwise
return 1

262
deploy/openstack.sh Normal file
View File

@ -0,0 +1,262 @@
#!/usr/bin/env sh
# OpenStack Barbican deploy hook
#
# This requires you to have OpenStackClient and python-barbicanclient
# installed.
#
# You will require Keystone V3 credentials loaded into your environment, which
# could be either password or v3applicationcredential type.
#
# Author: Andy Botting <andy@andybotting.com>
openstack_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
if ! _exists openstack; then
_err "OpenStack client not found"
return 1
fi
_openstack_credentials || return $?
_info "Generate import pkcs12"
_import_pkcs12="$(_mktemp)"
if ! _openstack_to_pkcs "$_import_pkcs12" "$_ckey" "$_ccert" "$_cca"; then
_err "Error creating pkcs12 certificate"
return 1
fi
_debug _import_pkcs12 "$_import_pkcs12"
_base64_pkcs12=$(_base64 "multiline" <"$_import_pkcs12")
secretHrefs=$(_openstack_get_secrets)
_debug secretHrefs "$secretHrefs"
_openstack_store_secret || return $?
if [ -n "$secretHrefs" ]; then
_info "Cleaning up existing secret"
_openstack_delete_secrets || return $?
fi
_info "Certificate successfully deployed"
return 0
}
_openstack_store_secret() {
if ! openstack secret store --name "$_cdomain." -t 'application/octet-stream' -e base64 --payload "$_base64_pkcs12"; then
_err "Failed to create OpenStack secret"
return 1
fi
return
}
_openstack_delete_secrets() {
echo "$secretHrefs" | while read -r secretHref; do
_info "Deleting old secret $secretHref"
if ! openstack secret delete "$secretHref"; then
_err "Failed to delete OpenStack secret"
return 1
fi
done
return
}
_openstack_get_secrets() {
if ! secretHrefs=$(openstack secret list -f value --name "$_cdomain." | cut -d' ' -f1); then
_err "Failed to list secrets"
return 1
fi
echo "$secretHrefs"
}
_openstack_to_pkcs() {
# The existing _toPkcs command can't allow an empty password, due to sh
# -z test, so copied here and forcing the empty password.
_cpfx="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
${ACME_OPENSSL_BIN:-openssl} pkcs12 -export -out "$_cpfx" -inkey "$_ckey" -in "$_ccert" -certfile "$_cca" -password "pass:"
}
_openstack_credentials() {
_debug "Check OpenStack credentials"
# If we have OS_AUTH_URL already set in the environment, then assume we want
# to use those, otherwise use stored credentials
if [ -n "$OS_AUTH_URL" ]; then
_debug "OS_AUTH_URL env var found, using environment"
else
_debug "OS_AUTH_URL not found, loading stored credentials"
OS_AUTH_URL="${OS_AUTH_URL:-$(_readaccountconf_mutable OS_AUTH_URL)}"
OS_IDENTITY_API_VERSION="${OS_IDENTITY_API_VERSION:-$(_readaccountconf_mutable OS_IDENTITY_API_VERSION)}"
OS_AUTH_TYPE="${OS_AUTH_TYPE:-$(_readaccountconf_mutable OS_AUTH_TYPE)}"
OS_APPLICATION_CREDENTIAL_ID="${OS_APPLICATION_CREDENTIAL_ID:-$(_readaccountconf_mutable OS_APPLICATION_CREDENTIAL_ID)}"
OS_APPLICATION_CREDENTIAL_SECRET="${OS_APPLICATION_CREDENTIAL_SECRET:-$(_readaccountconf_mutable OS_APPLICATION_CREDENTIAL_SECRET)}"
OS_USERNAME="${OS_USERNAME:-$(_readaccountconf_mutable OS_USERNAME)}"
OS_PASSWORD="${OS_PASSWORD:-$(_readaccountconf_mutable OS_PASSWORD)}"
OS_PROJECT_NAME="${OS_PROJECT_NAME:-$(_readaccountconf_mutable OS_PROJECT_NAME)}"
OS_PROJECT_ID="${OS_PROJECT_ID:-$(_readaccountconf_mutable OS_PROJECT_ID)}"
OS_USER_DOMAIN_NAME="${OS_USER_DOMAIN_NAME:-$(_readaccountconf_mutable OS_USER_DOMAIN_NAME)}"
OS_USER_DOMAIN_ID="${OS_USER_DOMAIN_ID:-$(_readaccountconf_mutable OS_USER_DOMAIN_ID)}"
OS_PROJECT_DOMAIN_NAME="${OS_PROJECT_DOMAIN_NAME:-$(_readaccountconf_mutable OS_PROJECT_DOMAIN_NAME)}"
OS_PROJECT_DOMAIN_ID="${OS_PROJECT_DOMAIN_ID:-$(_readaccountconf_mutable OS_PROJECT_DOMAIN_ID)}"
fi
# Check each var and either save or clear it depending on whether its set.
# The helps us clear out old vars in the case where a user may want
# to switch between password and app creds
_debug "OS_AUTH_URL" "$OS_AUTH_URL"
if [ -n "$OS_AUTH_URL" ]; then
export OS_AUTH_URL
_saveaccountconf_mutable OS_AUTH_URL "$OS_AUTH_URL"
else
unset OS_AUTH_URL
_clearaccountconf SAVED_OS_AUTH_URL
fi
_debug "OS_IDENTITY_API_VERSION" "$OS_IDENTITY_API_VERSION"
if [ -n "$OS_IDENTITY_API_VERSION" ]; then
export OS_IDENTITY_API_VERSION
_saveaccountconf_mutable OS_IDENTITY_API_VERSION "$OS_IDENTITY_API_VERSION"
else
unset OS_IDENTITY_API_VERSION
_clearaccountconf SAVED_OS_IDENTITY_API_VERSION
fi
_debug "OS_AUTH_TYPE" "$OS_AUTH_TYPE"
if [ -n "$OS_AUTH_TYPE" ]; then
export OS_AUTH_TYPE
_saveaccountconf_mutable OS_AUTH_TYPE "$OS_AUTH_TYPE"
else
unset OS_AUTH_TYPE
_clearaccountconf SAVED_OS_AUTH_TYPE
fi
_debug "OS_APPLICATION_CREDENTIAL_ID" "$OS_APPLICATION_CREDENTIAL_ID"
if [ -n "$OS_APPLICATION_CREDENTIAL_ID" ]; then
export OS_APPLICATION_CREDENTIAL_ID
_saveaccountconf_mutable OS_APPLICATION_CREDENTIAL_ID "$OS_APPLICATION_CREDENTIAL_ID"
else
unset OS_APPLICATION_CREDENTIAL_ID
_clearaccountconf SAVED_OS_APPLICATION_CREDENTIAL_ID
fi
_secure_debug "OS_APPLICATION_CREDENTIAL_SECRET" "$OS_APPLICATION_CREDENTIAL_SECRET"
if [ -n "$OS_APPLICATION_CREDENTIAL_SECRET" ]; then
export OS_APPLICATION_CREDENTIAL_SECRET
_saveaccountconf_mutable OS_APPLICATION_CREDENTIAL_SECRET "$OS_APPLICATION_CREDENTIAL_SECRET"
else
unset OS_APPLICATION_CREDENTIAL_SECRET
_clearaccountconf SAVED_OS_APPLICATION_CREDENTIAL_SECRET
fi
_debug "OS_USERNAME" "$OS_USERNAME"
if [ -n "$OS_USERNAME" ]; then
export OS_USERNAME
_saveaccountconf_mutable OS_USERNAME "$OS_USERNAME"
else
unset OS_USERNAME
_clearaccountconf SAVED_OS_USERNAME
fi
_secure_debug "OS_PASSWORD" "$OS_PASSWORD"
if [ -n "$OS_PASSWORD" ]; then
export OS_PASSWORD
_saveaccountconf_mutable OS_PASSWORD "$OS_PASSWORD"
else
unset OS_PASSWORD
_clearaccountconf SAVED_OS_PASSWORD
fi
_debug "OS_PROJECT_NAME" "$OS_PROJECT_NAME"
if [ -n "$OS_PROJECT_NAME" ]; then
export OS_PROJECT_NAME
_saveaccountconf_mutable OS_PROJECT_NAME "$OS_PROJECT_NAME"
else
unset OS_PROJECT_NAME
_clearaccountconf SAVED_OS_PROJECT_NAME
fi
_debug "OS_PROJECT_ID" "$OS_PROJECT_ID"
if [ -n "$OS_PROJECT_ID" ]; then
export OS_PROJECT_ID
_saveaccountconf_mutable OS_PROJECT_ID "$OS_PROJECT_ID"
else
unset OS_PROJECT_ID
_clearaccountconf SAVED_OS_PROJECT_ID
fi
_debug "OS_USER_DOMAIN_NAME" "$OS_USER_DOMAIN_NAME"
if [ -n "$OS_USER_DOMAIN_NAME" ]; then
export OS_USER_DOMAIN_NAME
_saveaccountconf_mutable OS_USER_DOMAIN_NAME "$OS_USER_DOMAIN_NAME"
else
unset OS_USER_DOMAIN_NAME
_clearaccountconf SAVED_OS_USER_DOMAIN_NAME
fi
_debug "OS_USER_DOMAIN_ID" "$OS_USER_DOMAIN_ID"
if [ -n "$OS_USER_DOMAIN_ID" ]; then
export OS_USER_DOMAIN_ID
_saveaccountconf_mutable OS_USER_DOMAIN_ID "$OS_USER_DOMAIN_ID"
else
unset OS_USER_DOMAIN_ID
_clearaccountconf SAVED_OS_USER_DOMAIN_ID
fi
_debug "OS_PROJECT_DOMAIN_NAME" "$OS_PROJECT_DOMAIN_NAME"
if [ -n "$OS_PROJECT_DOMAIN_NAME" ]; then
export OS_PROJECT_DOMAIN_NAME
_saveaccountconf_mutable OS_PROJECT_DOMAIN_NAME "$OS_PROJECT_DOMAIN_NAME"
else
unset OS_PROJECT_DOMAIN_NAME
_clearaccountconf SAVED_OS_PROJECT_DOMAIN_NAME
fi
_debug "OS_PROJECT_DOMAIN_ID" "$OS_PROJECT_DOMAIN_ID"
if [ -n "$OS_PROJECT_DOMAIN_ID" ]; then
export OS_PROJECT_DOMAIN_ID
_saveaccountconf_mutable OS_PROJECT_DOMAIN_ID "$OS_PROJECT_DOMAIN_ID"
else
unset OS_PROJECT_DOMAIN_ID
_clearaccountconf SAVED_OS_PROJECT_DOMAIN_ID
fi
if [ "$OS_AUTH_TYPE" = "v3applicationcredential" ]; then
# Application Credential auth
if [ -z "$OS_APPLICATION_CREDENTIAL_ID" ] || [ -z "$OS_APPLICATION_CREDENTIAL_SECRET" ]; then
_err "When using OpenStack application credentials, OS_APPLICATION_CREDENTIAL_ID"
_err "and OS_APPLICATION_CREDENTIAL_SECRET must be set."
_err "Please check your credentials and try again."
return 1
fi
else
# Password auth
if [ -z "$OS_USERNAME" ] || [ -z "$OS_PASSWORD" ]; then
_err "OpenStack username or password not found."
_err "Please check your credentials and try again."
return 1
fi
if [ -z "$OS_PROJECT_NAME" ] && [ -z "$OS_PROJECT_ID" ]; then
_err "When using password authentication, OS_PROJECT_NAME or"
_err "OS_PROJECT_ID must be set."
_err "Please check your credentials and try again."
return 1
fi
fi
return 0
}

View File

@ -22,7 +22,7 @@
######## Public functions #####################
_syno_get_cookie_data() {
grep "\W$1=" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';'
grep -i "\W$1=" | grep -i "^Set-Cookie:" | _tail_n 1 | _egrep_o "$1=[^;]*;" | tr -d ';'
}
#domain keyfile certfile cafile fullchain
@ -79,7 +79,7 @@ synology_dsm_deploy() {
encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)"
encoded_did="$(printf "%s" "$SYNO_DID" | _url_encode)"
response=$(_get "$_base_url/webman/login.cgi?username=$encoded_username&passwd=$encoded_password&enable_syno_token=yes&device_id=$encoded_did" 1)
token=$(echo "$response" | grep "X-SYNO-TOKEN:" | sed -n 's/^X-SYNO-TOKEN: \(.*\)$/\1/p' | tr -d "\r\n")
token=$(echo "$response" | grep -i "X-SYNO-TOKEN:" | sed -n 's/^X-SYNO-TOKEN: \(.*\)$/\1/pI' | tr -d "\r\n")
_debug3 response "$response"
_debug token "$token"

View File

@ -43,7 +43,7 @@ vault_cli_deploy() {
return 1
fi
VAULT_CMD=$(which vault)
VAULT_CMD=$(command -v vault)
if [ ! $? ]; then
_err "cannot find vault binary!"
return 1

View File

@ -3,7 +3,7 @@
#So, here must be a method dns_1984hosting_add()
#Which will be called by acme.sh to add the txt record to your api system.
#returns 0 means success, otherwise error.
#
#Author: Adrian Fedoreanu
#Report Bugs here: https://github.com/acmesh-official/acme.sh
# or here... https://github.com/acmesh-official/acme.sh/issues/2851
@ -100,7 +100,7 @@ _1984hosting_add_txt_record() {
elif _contains "$response" "<html>"; then
_err "1984Hosting failed to add TXT record for $subdomain. Check $HTTP_HEADER file"
return 1
elif [ "$response" = '{"auth": false, "ok": false}' ]; then
elif _contains "$response" '"auth": false'; then
_err "1984Hosting failed to add TXT record for $subdomain. Invalid or expired cookie"
return 1
fi
@ -167,7 +167,7 @@ _1984hosting_login() {
response="$(echo "$response" | _normalizeJson)"
_debug2 response "$response"
if [ "$response" = '{"loggedin": true, "ok": true}' ]; then
if _contains "$response" '"loggedin": true'; then
One984HOSTING_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _tail_n 1 | _egrep_o 'sessionid=[^;]*;' | tr -d ';')"
export One984HOSTING_COOKIE
_saveaccountconf_mutable One984HOSTING_COOKIE "$One984HOSTING_COOKIE"
@ -196,7 +196,7 @@ _check_cookie() {
_authget "https://management.1984hosting.com/accounts/loginstatus/"
response="$(echo "$_response" | _normalizeJson)"
if [ "$_response" = '{"ok": true}' ]; then
if _contains "$response" '"ok": true'; then
_debug "Cached cookie still valid"
return 0
fi

View File

@ -172,7 +172,7 @@ dns_azure_rm() {
_azure_rest GET "$acmeRecordURI" "" "$accesstoken"
timestamp="$(_time)"
if [ "$_code" = "200" ]; then
vlist="$(echo "$response" | _egrep_o "\"value\"\\s*:\\s*\\[\\s*\"[^\"]*\"\\s*]" | cut -d : -f 2 | tr -d "[]\"" | grep -v "$txtvalue")"
vlist="$(echo "$response" | _egrep_o "\"value\"\\s*:\\s*\\[\\s*\"[^\"]*\"\\s*]" | cut -d : -f 2 | tr -d "[]\"" | grep -v -- "$txtvalue")"
values=""
comma=""
for v in $vlist; do

View File

@ -69,7 +69,7 @@ dns_cloudns_rm() {
for i in $(echo "$response" | tr '{' "\n" | grep "$record"); do
record_id=$(echo "$i" | tr ',' "\n" | grep -E '^"id"' | sed -re 's/^\"id\"\:\"([0-9]+)\"$/\1/g')
if [ ! -z "$record_id" ]; then
if [ -n "$record_id" ]; then
_debug zone "$zone"
_debug host "$host"
_debug record "$record"
@ -91,7 +91,7 @@ dns_cloudns_rm() {
#################### Private functions below ##################################
_dns_cloudns_init_check() {
if [ ! -z "$CLOUDNS_INIT_CHECK_COMPLETED" ]; then
if [ -n "$CLOUDNS_INIT_CHECK_COMPLETED" ]; then
return 0
fi
@ -164,7 +164,7 @@ _dns_cloudns_http_api_call() {
_debug CLOUDNS_SUB_AUTH_ID "$CLOUDNS_SUB_AUTH_ID"
_debug CLOUDNS_AUTH_PASSWORD "$CLOUDNS_AUTH_PASSWORD"
if [ ! -z "$CLOUDNS_SUB_AUTH_ID" ]; then
if [ -n "$CLOUDNS_SUB_AUTH_ID" ]; then
auth_user="sub-auth-id=$CLOUDNS_SUB_AUTH_ID"
else
auth_user="auth-id=$CLOUDNS_AUTH_ID"

View File

@ -66,7 +66,7 @@ _cyon_load_credentials() {
_debug "Save credentials to account.conf"
_saveaccountconf CY_Username "${CY_Username}"
_saveaccountconf CY_Password_B64 "$CY_Password_B64"
if [ ! -z "${CY_OTP_Secret}" ]; then
if [ -n "${CY_OTP_Secret}" ]; then
_saveaccountconf CY_OTP_Secret "$CY_OTP_Secret"
else
_clearaccountconf CY_OTP_Secret
@ -164,7 +164,7 @@ _cyon_login() {
# todo: instead of just checking if the env variable is defined, check if we actually need to do a 2FA auth request.
# 2FA authentication with OTP?
if [ ! -z "${CY_OTP_Secret}" ]; then
if [ -n "${CY_OTP_Secret}" ]; then
_info " - Authorising with OTP code..."
if ! _exists oathtool; then

View File

@ -122,12 +122,12 @@ dns_dgon_rm() {
## check for what we are looking for: "type":"A","name":"$_sub_domain"
record="$(echo "$domain_list" | _egrep_o "\"id\"\s*\:\s*\"*[0-9]+\"*[^}]*\"name\"\s*\:\s*\"$_sub_domain\"[^}]*\"data\"\s*\:\s*\"$txtvalue\"")"
if [ ! -z "$record" ]; then
if [ -n "$record" ]; then
## we found records
rec_ids="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")"
_debug rec_ids "$rec_ids"
if [ ! -z "$rec_ids" ]; then
if [ -n "$rec_ids" ]; then
echo "$rec_ids" | while IFS= read -r rec_id; do
## delete the record
## delete URL for removing the one we dont want
@ -218,7 +218,7 @@ _get_base_domain() {
## we got part of a domain back - grep it out
found="$(echo "$domain_list" | _egrep_o "\"name\"\s*\:\s*\"$_domain\"")"
## check if it exists
if [ ! -z "$found" ]; then
if [ -n "$found" ]; then
## exists - exit loop returning the parts
sub_point=$(_math $i - 1)
_sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-"$sub_point")

View File

@ -80,7 +80,7 @@ _generate_new_key() {
_get_domain() {
_full_domain="$1"
_debug "getting domain for $_full_domain"
if ! _contains "$_full_domain" 'dynv6.net' && ! _contains "$_full_domain" 'dns.army' && ! _contains "$_full_domain" 'dns.navy'; then
if ! _contains "$_full_domain" 'dynv6.net' && ! _contains "$_full_domain" 'dns.army' && ! _contains "$_full_domain" 'dns.navy' && ! _contains "$_full_domain" 'v6.rocks' ; then
_err "The hosts does not seem to be a dynv6 host"
return 1
fi

160
dnsapi/dns_netlify.sh Normal file
View File

@ -0,0 +1,160 @@
#!/usr/bin/env sh
#NETLIFY_ACCESS_TOKEN="xxxx"
NETLIFY_HOST="api.netlify.com/api/v1/"
NETLIFY_URL="https://$NETLIFY_HOST"
######## Public functions #####################
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_netlify_add() {
fulldomain=$1
txtvalue=$2
NETLIFY_ACCESS_TOKEN="${NETLIFY_ACCESS_TOKEN:-$(_readaccountconf_mutable NETLIFY_ACCESS_TOKEN)}"
if [ -z "$NETLIFY_ACCESS_TOKEN" ]; then
NETLIFY_ACCESS_TOKEN=""
_err "Please specify your Netlify Access Token and try again."
return 1
fi
_info "Using Netlify"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_saveaccountconf_mutable NETLIFY_ACCESS_TOKEN "$NETLIFY_ACCESS_TOKEN"
if ! _get_root "$fulldomain" "$accesstoken"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
dnsRecordURI="dns_zones/$_domain_id/dns_records"
body="{\"type\":\"TXT\", \"hostname\":\"$_sub_domain\", \"value\":\"$txtvalue\", \"ttl\":\"10\"}"
_netlify_rest POST "$dnsRecordURI" "$body" "$NETLIFY_ACCESS_TOKEN"
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
if [ "$_code" = "200" ] || [ "$_code" = '201' ]; then
_info "validation value added"
return 0
else
_err "error adding validation value ($_code)"
return 1
fi
_err "Not fully implemented!"
return 1
}
#Usage: dns_myapi_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
#Remove the txt record after validation.
dns_netlify_rm() {
_info "Using Netlify"
_debug txtdomain "$txtdomain"
_debug txt "$txt"
_saveaccountconf_mutable NETLIFY_ACCESS_TOKEN "$NETLIFY_ACCESS_TOKEN"
if ! _get_root "$txtdomain" "$accesstoken"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "$_domain_id"
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
dnsRecordURI="dns_zones/$_domain_id/dns_records"
_netlify_rest GET "$dnsRecordURI" "" "$NETLIFY_ACCESS_TOKEN"
_record_id=$(echo "$response" | _egrep_o "\"type\":\"TXT\",[^\}]*\"value\":\"$txt\"" | head -n 1 | _egrep_o "\"id\":\"[^\"\}]*\"" | cut -d : -f 2 | tr -d \" )
_debug _record_id "$_record_id"
if [ "$_record_id" ]; then
_netlify_rest DELETE "$dnsRecordURI/$_record_id" "" "$NETLIFY_ACCESS_TOKEN"
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
if [ "$_code" = "200" ] || [ "$_code" = '204' ]; then
_info "validation value removed"
return 0
else
_err "error removing validation value ($_code)"
return 1
fi
return 0
fi
return 1
}
#################### Private functions below ##################################
_get_root() {
domain=$1
accesstoken=$2
i=1
p=1
_netlify_rest GET "dns_zones" "" "$accesstoken"
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug2 "Checking domain: $h"
if [ -z "$h" ]; then
#not valid
_err "Invalid domain"
return 1
fi
if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
_domain_id=$(echo "$response" | _egrep_o "\"[^\"]*\",\"name\":\"$h" | cut -d , -f 1 | tr -d \" )
if [ "$_domain_id" ]; then
if [ "$i" = 1 ]; then
#create the record at the domain apex (@) if only the domain name was provided as --domain-alias
_sub_domain="@"
else
_sub_domain=$(echo "$domain" | cut -d . -f 1-$p)
fi
_domain=$h
return 0
fi
return 1
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_netlify_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
token_trimmed=$(echo "$NETLIFY_ACCESS_TOKEN" | tr -d '"')
export _H1="Content-Type: application/json"
export _H2="Authorization: Bearer $token_trimmed"
:>"$HTTP_HEADER"
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$NETLIFY_URL$ep" "" "$m")"
else
response="$(_get "$NETLIFY_URL$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}

View File

@ -25,7 +25,7 @@ dns_yandex_add() {
_PDD_get_record_ids || return 1
_debug "Record_ids: $record_ids"
if [ ! -z "$record_ids" ]; then
if [ -n "$record_ids" ]; then
_info "All existing $subdomain records from $domain will be removed at the very end."
fi

348
dnsapi/openstack.sh Executable file
View File

@ -0,0 +1,348 @@
#!/usr/bin/env sh
# OpenStack Designate API plugin
#
# This requires you to have OpenStackClient and python-desginateclient
# installed.
#
# You will require Keystone V3 credentials loaded into your environment, which
# could be either password or v3applicationcredential type.
#
# Author: Andy Botting <andy@andybotting.com>
######## Public functions #####################
# Usage: dns_openstack_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_openstack_add() {
fulldomain=$1
txtvalue=$2
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_dns_openstack_credentials || return $?
_dns_openstack_check_setup || return $?
_dns_openstack_find_zone || return $?
_dns_openstack_get_recordset || return $?
_debug _recordset_id "$_recordset_id"
if [ -n "$_recordset_id" ]; then
_dns_openstack_get_records || return $?
_debug _records "$_records"
fi
_dns_openstack_create_recordset || return $?
}
# Usage: dns_openstack_rm _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
# Remove the txt record after validation.
dns_openstack_rm() {
fulldomain=$1
txtvalue=$2
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
_dns_openstack_credentials || return $?
_dns_openstack_check_setup || return $?
_dns_openstack_find_zone || return $?
_dns_openstack_get_recordset || return $?
_debug _recordset_id "$_recordset_id"
if [ -n "$_recordset_id" ]; then
_dns_openstack_get_records || return $?
_debug _records "$_records"
fi
_dns_openstack_delete_recordset || return $?
}
#################### Private functions below ##################################
_dns_openstack_create_recordset() {
if [ -z "$_recordset_id" ]; then
_info "Creating a new recordset"
if ! _recordset_id=$(openstack recordset create -c id -f value --type TXT --record "$txtvalue" "$_zone_id" "$fulldomain."); then
_err "No recordset ID found after create"
return 1
fi
else
_info "Updating existing recordset"
# Build new list of --record <rec> args for update
_record_args="--record $txtvalue"
for _rec in $_records; do
_record_args="$_record_args --record $_rec"
done
# shellcheck disable=SC2086
if ! _recordset_id=$(openstack recordset set -c id -f value $_record_args "$_zone_id" "$fulldomain."); then
_err "Recordset update failed"
return 1
fi
fi
_max_retries=60
_sleep_sec=5
_retry_times=0
while [ "$_retry_times" -lt "$_max_retries" ]; do
_retry_times=$(_math "$_retry_times" + 1)
_debug3 _retry_times "$_retry_times"
_record_status=$(openstack recordset show -c status -f value "$_zone_id" "$_recordset_id")
_info "Recordset status is $_record_status"
if [ "$_record_status" = "ACTIVE" ]; then
return 0
elif [ "$_record_status" = "ERROR" ]; then
return 1
else
_sleep $_sleep_sec
fi
done
_err "Recordset failed to become ACTIVE"
return 1
}
_dns_openstack_delete_recordset() {
if [ "$_records" = "$txtvalue" ]; then
_info "Only one record found, deleting recordset"
if ! openstack recordset delete "$_zone_id" "$fulldomain." >/dev/null; then
_err "Failed to delete recordset"
return 1
fi
else
_info "Found existing records, updating recordset"
# Build new list of --record <rec> args for update
_record_args=""
for _rec in $_records; do
if [ "$_rec" = "$txtvalue" ]; then
continue
fi
_record_args="$_record_args --record $_rec"
done
# shellcheck disable=SC2086
if ! openstack recordset set -c id -f value $_record_args "$_zone_id" "$fulldomain." >/dev/null; then
_err "Recordset update failed"
return 1
fi
fi
}
_dns_openstack_get_root() {
# Take the full fqdn and strip away pieces until we get an exact zone name
# match. For example, _acme-challenge.something.domain.com might need to go
# into something.domain.com or domain.com
_zone_name=$1
_zone_list=$2
while [ "$_zone_name" != "" ]; do
_zone_name="$(echo "$_zone_name" | sed 's/[^.]*\.*//')"
echo "$_zone_list" | while read -r id name; do
if _startswith "$_zone_name." "$name"; then
echo "$id"
fi
done
done | _head_n 1
}
_dns_openstack_find_zone() {
if ! _zone_list="$(openstack zone list -c id -c name -f value)"; then
_err "Can't list zones. Check your OpenStack credentials"
return 1
fi
_debug _zone_list "$_zone_list"
if ! _zone_id="$(_dns_openstack_get_root "$fulldomain" "$_zone_list")"; then
_err "Can't find a matching zone. Check your OpenStack credentials"
return 1
fi
_debug _zone_id "$_zone_id"
}
_dns_openstack_get_records() {
if ! _records=$(openstack recordset show -c records -f value "$_zone_id" "$fulldomain."); then
_err "Failed to get records"
return 1
fi
return 0
}
_dns_openstack_get_recordset() {
if ! _recordset_id=$(openstack recordset list -c id -f value --name "$fulldomain." "$_zone_id"); then
_err "Failed to get recordset"
return 1
fi
return 0
}
_dns_openstack_check_setup() {
if ! _exists openstack; then
_err "OpenStack client not found"
return 1
fi
}
_dns_openstack_credentials() {
_debug "Check OpenStack credentials"
# If we have OS_AUTH_URL already set in the environment, then assume we want
# to use those, otherwise use stored credentials
if [ -n "$OS_AUTH_URL" ]; then
_debug "OS_AUTH_URL env var found, using environment"
else
_debug "OS_AUTH_URL not found, loading stored credentials"
OS_AUTH_URL="${OS_AUTH_URL:-$(_readaccountconf_mutable OS_AUTH_URL)}"
OS_IDENTITY_API_VERSION="${OS_IDENTITY_API_VERSION:-$(_readaccountconf_mutable OS_IDENTITY_API_VERSION)}"
OS_AUTH_TYPE="${OS_AUTH_TYPE:-$(_readaccountconf_mutable OS_AUTH_TYPE)}"
OS_APPLICATION_CREDENTIAL_ID="${OS_APPLICATION_CREDENTIAL_ID:-$(_readaccountconf_mutable OS_APPLICATION_CREDENTIAL_ID)}"
OS_APPLICATION_CREDENTIAL_SECRET="${OS_APPLICATION_CREDENTIAL_SECRET:-$(_readaccountconf_mutable OS_APPLICATION_CREDENTIAL_SECRET)}"
OS_USERNAME="${OS_USERNAME:-$(_readaccountconf_mutable OS_USERNAME)}"
OS_PASSWORD="${OS_PASSWORD:-$(_readaccountconf_mutable OS_PASSWORD)}"
OS_PROJECT_NAME="${OS_PROJECT_NAME:-$(_readaccountconf_mutable OS_PROJECT_NAME)}"
OS_PROJECT_ID="${OS_PROJECT_ID:-$(_readaccountconf_mutable OS_PROJECT_ID)}"
OS_USER_DOMAIN_NAME="${OS_USER_DOMAIN_NAME:-$(_readaccountconf_mutable OS_USER_DOMAIN_NAME)}"
OS_USER_DOMAIN_ID="${OS_USER_DOMAIN_ID:-$(_readaccountconf_mutable OS_USER_DOMAIN_ID)}"
OS_PROJECT_DOMAIN_NAME="${OS_PROJECT_DOMAIN_NAME:-$(_readaccountconf_mutable OS_PROJECT_DOMAIN_NAME)}"
OS_PROJECT_DOMAIN_ID="${OS_PROJECT_DOMAIN_ID:-$(_readaccountconf_mutable OS_PROJECT_DOMAIN_ID)}"
fi
# Check each var and either save or clear it depending on whether its set.
# The helps us clear out old vars in the case where a user may want
# to switch between password and app creds
_debug "OS_AUTH_URL" "$OS_AUTH_URL"
if [ -n "$OS_AUTH_URL" ]; then
export OS_AUTH_URL
_saveaccountconf_mutable OS_AUTH_URL "$OS_AUTH_URL"
else
unset OS_AUTH_URL
_clearaccountconf SAVED_OS_AUTH_URL
fi
_debug "OS_IDENTITY_API_VERSION" "$OS_IDENTITY_API_VERSION"
if [ -n "$OS_IDENTITY_API_VERSION" ]; then
export OS_IDENTITY_API_VERSION
_saveaccountconf_mutable OS_IDENTITY_API_VERSION "$OS_IDENTITY_API_VERSION"
else
unset OS_IDENTITY_API_VERSION
_clearaccountconf SAVED_OS_IDENTITY_API_VERSION
fi
_debug "OS_AUTH_TYPE" "$OS_AUTH_TYPE"
if [ -n "$OS_AUTH_TYPE" ]; then
export OS_AUTH_TYPE
_saveaccountconf_mutable OS_AUTH_TYPE "$OS_AUTH_TYPE"
else
unset OS_AUTH_TYPE
_clearaccountconf SAVED_OS_AUTH_TYPE
fi
_debug "OS_APPLICATION_CREDENTIAL_ID" "$OS_APPLICATION_CREDENTIAL_ID"
if [ -n "$OS_APPLICATION_CREDENTIAL_ID" ]; then
export OS_APPLICATION_CREDENTIAL_ID
_saveaccountconf_mutable OS_APPLICATION_CREDENTIAL_ID "$OS_APPLICATION_CREDENTIAL_ID"
else
unset OS_APPLICATION_CREDENTIAL_ID
_clearaccountconf SAVED_OS_APPLICATION_CREDENTIAL_ID
fi
_secure_debug "OS_APPLICATION_CREDENTIAL_SECRET" "$OS_APPLICATION_CREDENTIAL_SECRET"
if [ -n "$OS_APPLICATION_CREDENTIAL_SECRET" ]; then
export OS_APPLICATION_CREDENTIAL_SECRET
_saveaccountconf_mutable OS_APPLICATION_CREDENTIAL_SECRET "$OS_APPLICATION_CREDENTIAL_SECRET"
else
unset OS_APPLICATION_CREDENTIAL_SECRET
_clearaccountconf SAVED_OS_APPLICATION_CREDENTIAL_SECRET
fi
_debug "OS_USERNAME" "$OS_USERNAME"
if [ -n "$OS_USERNAME" ]; then
export OS_USERNAME
_saveaccountconf_mutable OS_USERNAME "$OS_USERNAME"
else
unset OS_USERNAME
_clearaccountconf SAVED_OS_USERNAME
fi
_secure_debug "OS_PASSWORD" "$OS_PASSWORD"
if [ -n "$OS_PASSWORD" ]; then
export OS_PASSWORD
_saveaccountconf_mutable OS_PASSWORD "$OS_PASSWORD"
else
unset OS_PASSWORD
_clearaccountconf SAVED_OS_PASSWORD
fi
_debug "OS_PROJECT_NAME" "$OS_PROJECT_NAME"
if [ -n "$OS_PROJECT_NAME" ]; then
export OS_PROJECT_NAME
_saveaccountconf_mutable OS_PROJECT_NAME "$OS_PROJECT_NAME"
else
unset OS_PROJECT_NAME
_clearaccountconf SAVED_OS_PROJECT_NAME
fi
_debug "OS_PROJECT_ID" "$OS_PROJECT_ID"
if [ -n "$OS_PROJECT_ID" ]; then
export OS_PROJECT_ID
_saveaccountconf_mutable OS_PROJECT_ID "$OS_PROJECT_ID"
else
unset OS_PROJECT_ID
_clearaccountconf SAVED_OS_PROJECT_ID
fi
_debug "OS_USER_DOMAIN_NAME" "$OS_USER_DOMAIN_NAME"
if [ -n "$OS_USER_DOMAIN_NAME" ]; then
export OS_USER_DOMAIN_NAME
_saveaccountconf_mutable OS_USER_DOMAIN_NAME "$OS_USER_DOMAIN_NAME"
else
unset OS_USER_DOMAIN_NAME
_clearaccountconf SAVED_OS_USER_DOMAIN_NAME
fi
_debug "OS_USER_DOMAIN_ID" "$OS_USER_DOMAIN_ID"
if [ -n "$OS_USER_DOMAIN_ID" ]; then
export OS_USER_DOMAIN_ID
_saveaccountconf_mutable OS_USER_DOMAIN_ID "$OS_USER_DOMAIN_ID"
else
unset OS_USER_DOMAIN_ID
_clearaccountconf SAVED_OS_USER_DOMAIN_ID
fi
_debug "OS_PROJECT_DOMAIN_NAME" "$OS_PROJECT_DOMAIN_NAME"
if [ -n "$OS_PROJECT_DOMAIN_NAME" ]; then
export OS_PROJECT_DOMAIN_NAME
_saveaccountconf_mutable OS_PROJECT_DOMAIN_NAME "$OS_PROJECT_DOMAIN_NAME"
else
unset OS_PROJECT_DOMAIN_NAME
_clearaccountconf SAVED_OS_PROJECT_DOMAIN_NAME
fi
_debug "OS_PROJECT_DOMAIN_ID" "$OS_PROJECT_DOMAIN_ID"
if [ -n "$OS_PROJECT_DOMAIN_ID" ]; then
export OS_PROJECT_DOMAIN_ID
_saveaccountconf_mutable OS_PROJECT_DOMAIN_ID "$OS_PROJECT_DOMAIN_ID"
else
unset OS_PROJECT_DOMAIN_ID
_clearaccountconf SAVED_OS_PROJECT_DOMAIN_ID
fi
if [ "$OS_AUTH_TYPE" = "v3applicationcredential" ]; then
# Application Credential auth
if [ -z "$OS_APPLICATION_CREDENTIAL_ID" ] || [ -z "$OS_APPLICATION_CREDENTIAL_SECRET" ]; then
_err "When using OpenStack application credentials, OS_APPLICATION_CREDENTIAL_ID"
_err "and OS_APPLICATION_CREDENTIAL_SECRET must be set."
_err "Please check your credentials and try again."
return 1
fi
else
# Password auth
if [ -z "$OS_USERNAME" ] || [ -z "$OS_PASSWORD" ]; then
_err "OpenStack username or password not found."
_err "Please check your credentials and try again."
return 1
fi
if [ -z "$OS_PROJECT_NAME" ] && [ -z "$OS_PROJECT_ID" ]; then
_err "When using password authentication, OS_PROJECT_NAME or"
_err "OS_PROJECT_ID must be set."
_err "Please check your credentials and try again."
return 1
fi
fi
return 0
}