mirror of
https://github.com/acmesh-official/acme.sh.git
synced 2025-06-16 17:53:05 +00:00
Merge remote-tracking branch 'upsteam/dev' into dev
This commit is contained in:
commit
b0842b98d1
211
.github/workflows/DNS.yml
vendored
Normal file
211
.github/workflows/DNS.yml
vendored
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
name: DNS
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'dnsapi/*.sh'
|
||||||
|
- '.github/workflows/DNS.yml'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- 'dev'
|
||||||
|
paths:
|
||||||
|
- 'dnsapi/*.sh'
|
||||||
|
- '.github/workflows/DNS.yml'
|
||||||
|
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
CheckToken:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
hasToken: ${{ steps.step_one.outputs.hasToken }}
|
||||||
|
steps:
|
||||||
|
- name: Set the value
|
||||||
|
id: step_one
|
||||||
|
run: |
|
||||||
|
if [ "${{secrets.TokenName1}}" ] ; then
|
||||||
|
echo "::set-output name=hasToken::true"
|
||||||
|
else
|
||||||
|
echo "::set-output name=hasToken::false"
|
||||||
|
fi
|
||||||
|
- name: Check the value
|
||||||
|
run: echo ${{ steps.step_one.outputs.hasToken }}
|
||||||
|
|
||||||
|
Fail:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: CheckToken
|
||||||
|
if: "contains(needs.CheckToken.outputs.hasToken, 'false')"
|
||||||
|
steps:
|
||||||
|
- name: "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test"
|
||||||
|
run: |
|
||||||
|
echo "Read this: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Test"
|
||||||
|
if [ "${{github.actor}}" != "Neilpang" ]; then
|
||||||
|
false
|
||||||
|
fi
|
||||||
|
|
||||||
|
Docker:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: CheckToken
|
||||||
|
if: "contains(needs.CheckToken.outputs.hasToken, 'true')"
|
||||||
|
env:
|
||||||
|
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||||
|
TestingDomain: ${{ secrets.TestingDomain }}
|
||||||
|
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
|
||||||
|
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
|
||||||
|
CASE: le_test_dnsapi
|
||||||
|
TEST_LOCAL: 1
|
||||||
|
DEBUG: 1
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Clone acmetest
|
||||||
|
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||||
|
- name: Set env file
|
||||||
|
run: |
|
||||||
|
cd ../acmetest
|
||||||
|
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||||
|
echo "${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}" >> env.list
|
||||||
|
fi
|
||||||
|
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||||
|
echo "${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}" >> env.list
|
||||||
|
fi
|
||||||
|
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||||
|
echo "${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}" >> env.list
|
||||||
|
fi
|
||||||
|
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||||
|
echo "${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}" >> env.list
|
||||||
|
fi
|
||||||
|
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||||
|
echo "${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}" >> env.list
|
||||||
|
fi
|
||||||
|
echo "TEST_DNS_NO_WILDCARD" >> env.list
|
||||||
|
echo "TEST_DNS_SLEEP" >> env.list
|
||||||
|
- name: Run acmetest
|
||||||
|
run: cd ../acmetest && ./rundocker.sh testall
|
||||||
|
|
||||||
|
MacOS:
|
||||||
|
runs-on: macos-latest
|
||||||
|
needs: Docker
|
||||||
|
env:
|
||||||
|
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||||
|
TestingDomain: ${{ secrets.TestingDomain }}
|
||||||
|
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
|
||||||
|
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
|
||||||
|
CASE: le_test_dnsapi
|
||||||
|
TEST_LOCAL: 1
|
||||||
|
DEBUG: 1
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Install tools
|
||||||
|
run: brew install socat
|
||||||
|
- name: Clone acmetest
|
||||||
|
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||||
|
- name: Run acmetest
|
||||||
|
run: |
|
||||||
|
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||||
|
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
||||||
|
fi
|
||||||
|
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||||
|
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
||||||
|
fi
|
||||||
|
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||||
|
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
||||||
|
fi
|
||||||
|
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||||
|
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
||||||
|
fi
|
||||||
|
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||||
|
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
||||||
|
fi
|
||||||
|
cd ../acmetest
|
||||||
|
./letest.sh
|
||||||
|
|
||||||
|
Windows:
|
||||||
|
runs-on: windows-latest
|
||||||
|
needs: MacOS
|
||||||
|
env:
|
||||||
|
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||||
|
TestingDomain: ${{ secrets.TestingDomain }}
|
||||||
|
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
|
||||||
|
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
|
||||||
|
CASE: le_test_dnsapi
|
||||||
|
TEST_LOCAL: 1
|
||||||
|
DEBUG: 1
|
||||||
|
steps:
|
||||||
|
- name: Set git to use LF
|
||||||
|
run: |
|
||||||
|
git config --global core.autocrlf false
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Install cygwin base packages with chocolatey
|
||||||
|
run: |
|
||||||
|
choco config get cacheLocation
|
||||||
|
choco install --no-progress cygwin
|
||||||
|
shell: cmd
|
||||||
|
- name: Install cygwin additional packages
|
||||||
|
run: |
|
||||||
|
C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git
|
||||||
|
shell: cmd
|
||||||
|
- name: Set ENV
|
||||||
|
run: |
|
||||||
|
echo '::set-env name=PATH::C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin'
|
||||||
|
- name: Clone acmetest
|
||||||
|
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||||
|
- name: Run acmetest
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||||
|
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
||||||
|
fi
|
||||||
|
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||||
|
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
||||||
|
fi
|
||||||
|
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||||
|
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
||||||
|
fi
|
||||||
|
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||||
|
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
||||||
|
fi
|
||||||
|
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||||
|
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
||||||
|
fi
|
||||||
|
cd ../acmetest
|
||||||
|
./letest.sh
|
||||||
|
|
||||||
|
FreeBSD:
|
||||||
|
runs-on: macos-latest
|
||||||
|
needs: Windows
|
||||||
|
env:
|
||||||
|
TEST_DNS : ${{ secrets.TEST_DNS }}
|
||||||
|
TestingDomain: ${{ secrets.TestingDomain }}
|
||||||
|
TEST_DNS_NO_WILDCARD: ${{ secrets.TEST_DNS_NO_WILDCARD }}
|
||||||
|
TEST_DNS_SLEEP: ${{ secrets.TEST_DNS_SLEEP }}
|
||||||
|
CASE: le_test_dnsapi
|
||||||
|
TEST_LOCAL: 1
|
||||||
|
DEBUG: 1
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Clone acmetest
|
||||||
|
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||||
|
- uses: vmactions/freebsd-vm@v0.0.7
|
||||||
|
with:
|
||||||
|
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
|
||||||
|
prepare: pkg install -y socat curl
|
||||||
|
usesh: true
|
||||||
|
run: |
|
||||||
|
if [ "${{ secrets.TokenName1}}" ] ; then
|
||||||
|
export ${{ secrets.TokenName1}}=${{ secrets.TokenValue1}}
|
||||||
|
fi
|
||||||
|
if [ "${{ secrets.TokenName2}}" ] ; then
|
||||||
|
export ${{ secrets.TokenName2}}=${{ secrets.TokenValue2}}
|
||||||
|
fi
|
||||||
|
if [ "${{ secrets.TokenName3}}" ] ; then
|
||||||
|
export ${{ secrets.TokenName3}}=${{ secrets.TokenValue3}}
|
||||||
|
fi
|
||||||
|
if [ "${{ secrets.TokenName4}}" ] ; then
|
||||||
|
export ${{ secrets.TokenName4}}=${{ secrets.TokenValue4}}
|
||||||
|
fi
|
||||||
|
if [ "${{ secrets.TokenName5}}" ] ; then
|
||||||
|
export ${{ secrets.TokenName5}}=${{ secrets.TokenValue5}}
|
||||||
|
fi
|
||||||
|
cd ../acmetest
|
||||||
|
./letest.sh
|
||||||
|
|
||||||
|
|
||||||
|
|
116
.github/workflows/LetsEncrypt.yml
vendored
Normal file
116
.github/workflows/LetsEncrypt.yml
vendored
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
name: LetsEncrypt
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- '*'
|
||||||
|
paths:
|
||||||
|
- '**.sh'
|
||||||
|
- '**.yml'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- dev
|
||||||
|
paths:
|
||||||
|
- '**.sh'
|
||||||
|
- '**.yml'
|
||||||
|
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
CheckToken:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
hasToken: ${{ steps.step_one.outputs.hasToken }}
|
||||||
|
env:
|
||||||
|
NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }}
|
||||||
|
steps:
|
||||||
|
- name: Set the value
|
||||||
|
id: step_one
|
||||||
|
run: |
|
||||||
|
if [ "$NGROK_TOKEN" ] ; then
|
||||||
|
echo "::set-output name=hasToken::true"
|
||||||
|
else
|
||||||
|
echo "::set-output name=hasToken::false"
|
||||||
|
fi
|
||||||
|
- name: Check the value
|
||||||
|
run: echo ${{ steps.step_one.outputs.hasToken }}
|
||||||
|
|
||||||
|
Ubuntu:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: CheckToken
|
||||||
|
if: "contains(needs.CheckToken.outputs.hasToken, 'true')"
|
||||||
|
env:
|
||||||
|
NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }}
|
||||||
|
TEST_LOCAL: 1
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Install tools
|
||||||
|
run: sudo apt-get install -y socat
|
||||||
|
- name: Clone acmetest
|
||||||
|
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||||
|
- name: Run acmetest
|
||||||
|
run: cd ../acmetest && sudo --preserve-env ./letest.sh
|
||||||
|
|
||||||
|
MacOS:
|
||||||
|
runs-on: macos-latest
|
||||||
|
needs: Ubuntu
|
||||||
|
env:
|
||||||
|
NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }}
|
||||||
|
TEST_LOCAL: 1
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Install tools
|
||||||
|
run: brew install socat
|
||||||
|
- name: Clone acmetest
|
||||||
|
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||||
|
- name: Run acmetest
|
||||||
|
run: cd ../acmetest && sudo --preserve-env ./letest.sh
|
||||||
|
|
||||||
|
Windows:
|
||||||
|
runs-on: windows-latest
|
||||||
|
needs: MacOS
|
||||||
|
env:
|
||||||
|
NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }}
|
||||||
|
TEST_LOCAL: 1
|
||||||
|
#The 80 port is used by Windows server, we have to use a custom port, ngrok will also use this port.
|
||||||
|
Le_HTTPPort: 8888
|
||||||
|
steps:
|
||||||
|
- name: Set git to use LF
|
||||||
|
run: |
|
||||||
|
git config --global core.autocrlf false
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Install cygwin base packages with chocolatey
|
||||||
|
run: |
|
||||||
|
choco config get cacheLocation
|
||||||
|
choco install --no-progress cygwin
|
||||||
|
shell: cmd
|
||||||
|
- name: Install cygwin additional packages
|
||||||
|
run: |
|
||||||
|
C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -s http://mirrors.kernel.org/sourceware/cygwin/ -P socat,curl,cron,unzip,git
|
||||||
|
shell: cmd
|
||||||
|
- name: Set ENV
|
||||||
|
run: |
|
||||||
|
echo '::set-env name=PATH::C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin'
|
||||||
|
- name: Clone acmetest
|
||||||
|
shell: cmd
|
||||||
|
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||||
|
- name: Run acmetest
|
||||||
|
shell: cmd
|
||||||
|
run: cd ../acmetest && bash.exe -c ./letest.sh
|
||||||
|
|
||||||
|
FreeBSD:
|
||||||
|
runs-on: macos-latest
|
||||||
|
needs: Windows
|
||||||
|
env:
|
||||||
|
NGROK_TOKEN : ${{ secrets.NGROK_TOKEN }}
|
||||||
|
TEST_LOCAL: 1
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Clone acmetest
|
||||||
|
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||||
|
- uses: vmactions/freebsd-vm@v0.0.7
|
||||||
|
with:
|
||||||
|
envs: 'NGROK_TOKEN TEST_LOCAL'
|
||||||
|
prepare: pkg install -y socat curl
|
||||||
|
usesh: true
|
||||||
|
run: |
|
||||||
|
cd ../acmetest && ./letest.sh
|
||||||
|
|
39
.github/workflows/PebbleStrict.yml
vendored
Normal file
39
.github/workflows/PebbleStrict.yml
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
name: PebbleStrict
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- '*'
|
||||||
|
paths:
|
||||||
|
- '**.sh'
|
||||||
|
- '**.yml'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- dev
|
||||||
|
paths:
|
||||||
|
- '**.sh'
|
||||||
|
- '**.yml'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
PebbleStrict:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
TestingDomain: example.com
|
||||||
|
TestingAltDomains: www.example.com
|
||||||
|
ACME_DIRECTORY: https://localhost:14000/dir
|
||||||
|
HTTPS_INSECURE: 1
|
||||||
|
Le_HTTPPort: 5002
|
||||||
|
TEST_LOCAL: 1
|
||||||
|
TEST_CA: "Pebble Intermediate CA"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Install tools
|
||||||
|
run: sudo apt-get install -y socat
|
||||||
|
- name: Run Pebble
|
||||||
|
run: cd .. && curl https://raw.githubusercontent.com/letsencrypt/pebble/master/docker-compose.yml >docker-compose.yml && docker-compose up -d
|
||||||
|
- name: Set up Pebble
|
||||||
|
run: curl --request POST --data '{"ip":"10.30.50.1"}' http://localhost:8055/set-default-ipv4
|
||||||
|
- name: Clone acmetest
|
||||||
|
run: cd .. && git clone https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||||
|
- name: Run acmetest
|
||||||
|
run: cd ../acmetest && ./letest.sh
|
56
.github/workflows/dockerhub.yml
vendored
56
.github/workflows/dockerhub.yml
vendored
@ -2,15 +2,65 @@
|
|||||||
name: Build DockerHub
|
name: Build DockerHub
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ master, dev ]
|
branches:
|
||||||
|
- '*'
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
CheckToken:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
hasToken: ${{ steps.step_one.outputs.hasToken }}
|
||||||
|
env:
|
||||||
|
DOCKER_PASSWORD : ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
steps:
|
||||||
|
- name: Set the value
|
||||||
|
id: step_one
|
||||||
|
run: |
|
||||||
|
if [ "$DOCKER_PASSWORD" ] ; then
|
||||||
|
echo "::set-output name=hasToken::true"
|
||||||
|
else
|
||||||
|
echo "::set-output name=hasToken::false"
|
||||||
|
fi
|
||||||
|
- name: Check the value
|
||||||
|
run: echo ${{ steps.step_one.outputs.hasToken }}
|
||||||
|
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
needs: CheckToken
|
||||||
|
if: "contains(needs.CheckToken.outputs.hasToken, 'true')"
|
||||||
steps:
|
steps:
|
||||||
- name: trigger
|
- name: checkout code
|
||||||
run: curl -X POST https://hub.docker.com/api/build/v1/source/1813a660-2ee5-4583-a238-dd54e9a6ebac/trigger/c8cd9f1f-f269-45bc-9750-a08327257f62/call/
|
uses: actions/checkout@v2
|
||||||
|
- name: install buildx
|
||||||
|
id: buildx
|
||||||
|
uses: crazy-max/ghaction-docker-buildx@v3
|
||||||
|
with:
|
||||||
|
buildx-version: latest
|
||||||
|
qemu-version: latest
|
||||||
|
- name: login to docker hub
|
||||||
|
run: |
|
||||||
|
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
|
||||||
|
- name: build and push the image
|
||||||
|
run: |
|
||||||
|
DOCKER_IMAGE=neilpang/acme.sh
|
||||||
|
|
||||||
|
if [[ $GITHUB_REF == refs/tags/* ]]; then
|
||||||
|
DOCKER_IMAGE_TAG=${GITHUB_REF#refs/tags/}
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $GITHUB_REF == refs/heads/* ]]; then
|
||||||
|
DOCKER_IMAGE_TAG=${GITHUB_REF#refs/heads/}
|
||||||
|
|
||||||
|
if [[ $DOCKER_IMAGE_TAG == master ]]; then
|
||||||
|
DOCKER_IMAGE_TAG=latest
|
||||||
|
AUTO_UPGRADE=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
docker buildx build \
|
||||||
|
--tag ${DOCKER_IMAGE}:${DOCKER_IMAGE_TAG} \
|
||||||
|
--output "type=image,push=true" \
|
||||||
|
--build-arg AUTO_UPGRADE=${AUTO_UPGRADE} \
|
||||||
|
--platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7,linux/386,linux/ppc64le,linux/s390x .
|
||||||
|
33
.github/workflows/shellcheck.yml
vendored
Normal file
33
.github/workflows/shellcheck.yml
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
name: Shellcheck
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- '*'
|
||||||
|
paths:
|
||||||
|
- '**.sh'
|
||||||
|
- '**.yml'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- dev
|
||||||
|
paths:
|
||||||
|
- '**.sh'
|
||||||
|
- '**.yml'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ShellCheck:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Install Shellcheck
|
||||||
|
run: sudo apt-get install -y shellcheck
|
||||||
|
- name: DoShellcheck
|
||||||
|
run: shellcheck -V && shellcheck -e SC2181 **/*.sh && echo "shellcheck OK"
|
||||||
|
|
||||||
|
shfmt:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Install shfmt
|
||||||
|
run: curl -sSL https://github.com/mvdan/sh/releases/download/v3.1.2/shfmt_v3.1.2_linux_amd64 -o ~/shfmt && chmod +x ~/shfmt
|
||||||
|
- name: shfmt
|
||||||
|
run: ~/shfmt -l -w -i 2 . ; git diff --exit-code && echo "shfmt OK"
|
37
.travis.yml
37
.travis.yml
@ -1,37 +0,0 @@
|
|||||||
language: shell
|
|
||||||
dist: trusty
|
|
||||||
|
|
||||||
os:
|
|
||||||
- linux
|
|
||||||
- osx
|
|
||||||
|
|
||||||
services:
|
|
||||||
- docker
|
|
||||||
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- SHFMT_URL=https://github.com/mvdan/sh/releases/download/v0.4.0/shfmt_v0.4.0_linux_amd64
|
|
||||||
|
|
||||||
|
|
||||||
install:
|
|
||||||
- if [ "$TRAVIS_OS_NAME" = 'osx' ]; then
|
|
||||||
brew update && brew install socat;
|
|
||||||
export PATH="/usr/local/opt/openssl@1.1/bin:$PATH" ;
|
|
||||||
fi
|
|
||||||
|
|
||||||
script:
|
|
||||||
- echo "NGROK_TOKEN=$(echo "$NGROK_TOKEN" | wc -c)"
|
|
||||||
- command -V openssl && openssl version
|
|
||||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then curl -sSL $SHFMT_URL -o ~/shfmt && chmod +x ~/shfmt && ~/shfmt -l -w -i 2 . ; fi
|
|
||||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then git diff --exit-code && echo "shfmt OK" ; fi
|
|
||||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -V ; fi
|
|
||||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then shellcheck -e SC2181 **/*.sh && echo "shellcheck OK" ; fi
|
|
||||||
- cd ..
|
|
||||||
- git clone --depth 1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/ && cd acmetest
|
|
||||||
- if [ "$TRAVIS_OS_NAME" = "linux" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ./rundocker.sh testplat ubuntu:latest ; fi
|
|
||||||
- if [ "$TRAVIS_OS_NAME" = "osx" -a "$NGROK_TOKEN" ]; then sudo TEST_LOCAL="$TEST_LOCAL" NGROK_TOKEN="$NGROK_TOKEN" ACME_OPENSSL_BIN="$ACME_OPENSSL_BIN" ./letest.sh ; fi
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
fast_finish: true
|
|
||||||
|
|
||||||
|
|
@ -7,6 +7,7 @@ RUN apk update -f \
|
|||||||
coreutils \
|
coreutils \
|
||||||
bind-tools \
|
bind-tools \
|
||||||
curl \
|
curl \
|
||||||
|
sed \
|
||||||
socat \
|
socat \
|
||||||
tzdata \
|
tzdata \
|
||||||
oath-toolkit-oathtool \
|
oath-toolkit-oathtool \
|
||||||
@ -15,7 +16,9 @@ RUN apk update -f \
|
|||||||
|
|
||||||
ENV LE_CONFIG_HOME /acme.sh
|
ENV LE_CONFIG_HOME /acme.sh
|
||||||
|
|
||||||
ENV AUTO_UPGRADE 1
|
ARG AUTO_UPGRADE=1
|
||||||
|
|
||||||
|
ENV AUTO_UPGRADE $AUTO_UPGRADE
|
||||||
|
|
||||||
#Install
|
#Install
|
||||||
ADD ./ /install_acme.sh/
|
ADD ./ /install_acme.sh/
|
||||||
@ -52,6 +55,7 @@ RUN for verb in help \
|
|||||||
deactivate \
|
deactivate \
|
||||||
deactivate-account \
|
deactivate-account \
|
||||||
set-notify \
|
set-notify \
|
||||||
|
set-default-ca \
|
||||||
; do \
|
; do \
|
||||||
printf -- "%b" "#!/usr/bin/env sh\n/root/.acme.sh/acme.sh --${verb} --config-home /acme.sh \"\$@\"" >/usr/local/bin/--${verb} && chmod +x /usr/local/bin/--${verb} \
|
printf -- "%b" "#!/usr/bin/env sh\n/root/.acme.sh/acme.sh --${verb} --config-home /acme.sh \"\$@\"" >/usr/local/bin/--${verb} && chmod +x /usr/local/bin/--${verb} \
|
||||||
; done
|
; done
|
||||||
|
60
README.md
60
README.md
@ -1,13 +1,24 @@
|
|||||||
# An ACME Shell script: acme.sh [](https://travis-ci.org/acmesh-official/acme.sh)
|
# An ACME Shell script: 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>
|
||||||
|
[](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
[](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub")
|
||||||
|
[](https://hub.docker.com/r/neilpang/acme.sh "Click to view the image on Docker Hub")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<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> [](https://gitter.im/acme-sh/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
||||||
- An ACME protocol client written purely in Shell (Unix shell) language.
|
- An ACME protocol client written purely in Shell (Unix shell) language.
|
||||||
- Full ACME protocol implementation.
|
- Full ACME protocol implementation.
|
||||||
- Support ACME v1 and ACME v2
|
- Support ACME v1 and ACME v2
|
||||||
- Support ACME v2 wildcard certs
|
- Support ACME v2 wildcard certs
|
||||||
- Simple, powerful and very easy to use. You only need 3 minutes to learn it.
|
- Simple, powerful and very easy to use. You only need 3 minutes to learn it.
|
||||||
- Bash, dash and sh compatible.
|
- Bash, dash and sh compatible.
|
||||||
- Simplest shell script for Let's Encrypt free certificate client.
|
|
||||||
- Purely written in Shell with no dependencies on python or the official Let's Encrypt client.
|
- Purely written in Shell with no dependencies on python or the official Let's Encrypt client.
|
||||||
- Just one script to issue, renew and install your certificates automatically.
|
- Just one script to issue, renew and install your certificates automatically.
|
||||||
- DOES NOT require `root/sudoer` access.
|
- DOES NOT require `root/sudoer` access.
|
||||||
@ -46,26 +57,26 @@ Twitter: [@neilpangxa](https://twitter.com/neilpangxa)
|
|||||||
|
|
||||||
| NO | Status| Platform|
|
| NO | Status| Platform|
|
||||||
|----|-------|---------|
|
|----|-------|---------|
|
||||||
|1|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Ubuntu
|
|1|[](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Mac OSX
|
||||||
|2|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Debian
|
|2|[](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|Windows (cygwin with curl, openssl and crontab included)
|
||||||
|3|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|CentOS
|
|3|[](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)|FreeBSD
|
||||||
|4|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Windows (cygwin with curl, openssl and crontab included)
|
|4|[](https://github.com/acmesh-official/acme.sh/actions?query=workflow%3ALetsEncrypt)| Ubuntu
|
||||||
|5|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|FreeBSD
|
|5|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense
|
||||||
|6|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|pfsense
|
|6|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD
|
||||||
|7|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|openSUSE
|
|7|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|SunOS/Solaris
|
||||||
|8|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Alpine Linux (with curl)
|
|8|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)| Debian
|
||||||
|9|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Archlinux
|
|9|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|CentOS
|
||||||
|10|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|fedora
|
|10|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|openSUSE
|
||||||
|11|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Kali Linux
|
|11|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Alpine Linux (with curl)
|
||||||
|12|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Oracle Linux
|
|12|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Archlinux
|
||||||
|13|[](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management)
|
|13|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|fedora
|
||||||
|14|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111
|
|14|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Kali Linux
|
||||||
|15|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|OpenBSD
|
|15|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Oracle Linux
|
||||||
|16|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Mageia
|
|16|[](https://github.com/acmesh-official/letest#here-are-the-latest-status)| Proxmox: See Proxmox VE Wiki. Version [4.x, 5.0, 5.1](https://pve.proxmox.com/wiki/HTTPS_Certificate_Configuration_(Version_4.x,_5.0_and_5.1)#Let.27s_Encrypt_using_acme.sh), version [5.2 and up](https://pve.proxmox.com/wiki/Certificate_Management)
|
||||||
|17|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT)
|
|17|-----| Cloud Linux https://github.com/acmesh-official/acme.sh/issues/111
|
||||||
|18|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|SunOS/Solaris
|
|18|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Mageia
|
||||||
|19|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Gentoo Linux
|
|19|-----| OpenWRT: Tested and working. See [wiki page](https://github.com/acmesh-official/acme.sh/wiki/How-to-run-on-OpenWRT)
|
||||||
|20|[](https://travis-ci.org/acmesh-official/acme.sh)|Mac OSX
|
|20|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|Gentoo Linux
|
||||||
|21|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|ClearLinux
|
|21|[](https://github.com/acmesh-official/acmetest#here-are-the-latest-status)|ClearLinux
|
||||||
|
|
||||||
For all build statuses, check our [weekly build project](https://github.com/acmesh-official/acmetest):
|
For all build statuses, check our [weekly build project](https://github.com/acmesh-official/acmetest):
|
||||||
@ -75,6 +86,7 @@ https://github.com/acmesh-official/acmetest
|
|||||||
# Supported CA
|
# Supported CA
|
||||||
|
|
||||||
- Letsencrypt.org CA(default)
|
- Letsencrypt.org CA(default)
|
||||||
|
- [ZeroSSL.com CA](https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA)
|
||||||
- [BuyPass.com CA](https://github.com/acmesh-official/acme.sh/wiki/BuyPass.com-CA)
|
- [BuyPass.com CA](https://github.com/acmesh-official/acme.sh/wiki/BuyPass.com-CA)
|
||||||
- [Pebble strict Mode](https://github.com/letsencrypt/pebble)
|
- [Pebble strict Mode](https://github.com/letsencrypt/pebble)
|
||||||
|
|
||||||
@ -300,7 +312,7 @@ https://github.com/acmesh-official/acme.sh/wiki/dnsapi
|
|||||||
|
|
||||||
See: https://github.com/acmesh-official/acme.sh/wiki/dns-manual-mode first.
|
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
|
```bash
|
||||||
acme.sh --issue --dns -d example.com -d www.example.com -d cp.example.com
|
acme.sh --issue --dns -d example.com -d www.example.com -d cp.example.com
|
||||||
|
@ -69,8 +69,8 @@ exim4_deploy() {
|
|||||||
cp "$_exim4_conf" "$_backup_conf"
|
cp "$_exim4_conf" "$_backup_conf"
|
||||||
|
|
||||||
_info "Modify exim4 conf: $_exim4_conf"
|
_info "Modify exim4 conf: $_exim4_conf"
|
||||||
if _setopt "$_exim4_conf" "tls_certificate" "=" "$_real_fullchain" \
|
if _setopt "$_exim4_conf" "tls_certificate" "=" "$_real_fullchain" &&
|
||||||
&& _setopt "$_exim4_conf" "tls_privatekey" "=" "$_real_key"; then
|
_setopt "$_exim4_conf" "tls_privatekey" "=" "$_real_key"; then
|
||||||
_info "Set config success!"
|
_info "Set config success!"
|
||||||
else
|
else
|
||||||
_err "Config exim4 server error, please report bug to us."
|
_err "Config exim4 server error, please report bug to us."
|
||||||
|
262
deploy/openstack.sh
Normal file
262
deploy/openstack.sh
Normal 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
|
||||||
|
}
|
@ -195,8 +195,8 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d
|
|||||||
fi
|
fi
|
||||||
if [ -n "$Le_Deploy_ssh_cafile" ]; then
|
if [ -n "$Le_Deploy_ssh_cafile" ]; then
|
||||||
_pipe=">"
|
_pipe=">"
|
||||||
if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ] \
|
if [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_keyfile" ] ||
|
||||||
|| [ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then
|
[ "$Le_Deploy_ssh_cafile" = "$Le_Deploy_ssh_certfile" ]; then
|
||||||
# if filename is same as previous file then append.
|
# if filename is same as previous file then append.
|
||||||
_pipe=">>"
|
_pipe=">>"
|
||||||
elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then
|
elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then
|
||||||
@ -222,9 +222,9 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d
|
|||||||
fi
|
fi
|
||||||
if [ -n "$Le_Deploy_ssh_fullchain" ]; then
|
if [ -n "$Le_Deploy_ssh_fullchain" ]; then
|
||||||
_pipe=">"
|
_pipe=">"
|
||||||
if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ] \
|
if [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_keyfile" ] ||
|
||||||
|| [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ] \
|
[ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_certfile" ] ||
|
||||||
|| [ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then
|
[ "$Le_Deploy_ssh_fullchain" = "$Le_Deploy_ssh_cafile" ]; then
|
||||||
# if filename is same as previous file then append.
|
# if filename is same as previous file then append.
|
||||||
_pipe=">>"
|
_pipe=">>"
|
||||||
elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then
|
elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
######## Public functions #####################
|
######## Public functions #####################
|
||||||
|
|
||||||
_syno_get_cookie_data() {
|
_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
|
#domain keyfile certfile cafile fullchain
|
||||||
@ -79,7 +79,7 @@ synology_dsm_deploy() {
|
|||||||
encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)"
|
encoded_password="$(printf "%s" "$SYNO_Password" | _url_encode)"
|
||||||
encoded_did="$(printf "%s" "$SYNO_DID" | _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)
|
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"
|
_debug3 response "$response"
|
||||||
_debug token "$token"
|
_debug token "$token"
|
||||||
|
|
||||||
|
67
deploy/vault.sh
Normal file
67
deploy/vault.sh
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# Here is a script to deploy cert to hashicorp vault using curl
|
||||||
|
# (https://www.vaultproject.io/)
|
||||||
|
#
|
||||||
|
# it requires following environment variables:
|
||||||
|
#
|
||||||
|
# VAULT_PREFIX - this contains the prefix path in vault
|
||||||
|
# VAULT_ADDR - vault requires this to find your vault server
|
||||||
|
#
|
||||||
|
# additionally, you need to ensure that VAULT_TOKEN is avialable
|
||||||
|
# to access the vault server
|
||||||
|
|
||||||
|
#returns 0 means success, otherwise error.
|
||||||
|
|
||||||
|
######## Public functions #####################
|
||||||
|
|
||||||
|
#domain keyfile certfile cafile fullchain
|
||||||
|
vault_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"
|
||||||
|
|
||||||
|
# validate required env vars
|
||||||
|
_getdeployconf VAULT_PREFIX
|
||||||
|
if [ -z "$VAULT_PREFIX" ]; then
|
||||||
|
_err "VAULT_PREFIX needs to be defined (contains prefix path in vault)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_savedeployconf VAULT_PREFIX "$VAULT_PREFIX"
|
||||||
|
|
||||||
|
_getdeployconf VAULT_ADDR
|
||||||
|
if [ -z "$VAULT_ADDR" ]; then
|
||||||
|
_err "VAULT_ADDR needs to be defined (contains vault connection address)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_savedeployconf VAULT_ADDR "$VAULT_ADDR"
|
||||||
|
|
||||||
|
# JSON does not allow multiline strings.
|
||||||
|
# So replacing new-lines with "\n" here
|
||||||
|
_ckey=$(sed -z 's/\n/\\n/g' <"$2")
|
||||||
|
_ccert=$(sed -z 's/\n/\\n/g' <"$3")
|
||||||
|
_cca=$(sed -z 's/\n/\\n/g' <"$4")
|
||||||
|
_cfullchain=$(sed -z 's/\n/\\n/g' <"$5")
|
||||||
|
|
||||||
|
URL="$VAULT_ADDR/v1/$VAULT_PREFIX/$_cdomain"
|
||||||
|
export _H1="X-Vault-Token: $VAULT_TOKEN"
|
||||||
|
|
||||||
|
if [ -n "$FABIO" ]; then
|
||||||
|
_post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL"
|
||||||
|
else
|
||||||
|
_post "{\"value\": \"$_ccert\"}" "$URL/cert.pem"
|
||||||
|
_post "{\"value\": \"$_ckey\"}" "$URL/cert.key"
|
||||||
|
_post "{\"value\": \"$_cca\"}" "$URL/chain.pem"
|
||||||
|
_post "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem"
|
||||||
|
fi
|
||||||
|
|
||||||
|
}
|
@ -43,7 +43,7 @@ vault_cli_deploy() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
VAULT_CMD=$(which vault)
|
VAULT_CMD=$(command -v vault)
|
||||||
if [ ! $? ]; then
|
if [ ! $? ]; then
|
||||||
_err "cannot find vault binary!"
|
_err "cannot find vault binary!"
|
||||||
return 1
|
return 1
|
||||||
|
@ -65,9 +65,9 @@ vsftpd_deploy() {
|
|||||||
cp "$_vsftpd_conf" "$_backup_conf"
|
cp "$_vsftpd_conf" "$_backup_conf"
|
||||||
|
|
||||||
_info "Modify vsftpd conf: $_vsftpd_conf"
|
_info "Modify vsftpd conf: $_vsftpd_conf"
|
||||||
if _setopt "$_vsftpd_conf" "rsa_cert_file" "=" "$_real_fullchain" \
|
if _setopt "$_vsftpd_conf" "rsa_cert_file" "=" "$_real_fullchain" &&
|
||||||
&& _setopt "$_vsftpd_conf" "rsa_private_key_file" "=" "$_real_key" \
|
_setopt "$_vsftpd_conf" "rsa_private_key_file" "=" "$_real_key" &&
|
||||||
&& _setopt "$_vsftpd_conf" "ssl_enable" "=" "YES"; then
|
_setopt "$_vsftpd_conf" "ssl_enable" "=" "YES"; then
|
||||||
_info "Set config success!"
|
_info "Set config success!"
|
||||||
else
|
else
|
||||||
_err "Config vsftpd server error, please report bug to us."
|
_err "Config vsftpd server error, please report bug to us."
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#So, here must be a method dns_1984hosting_add()
|
#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.
|
#Which will be called by acme.sh to add the txt record to your api system.
|
||||||
#returns 0 means success, otherwise error.
|
#returns 0 means success, otherwise error.
|
||||||
#
|
|
||||||
#Author: Adrian Fedoreanu
|
#Author: Adrian Fedoreanu
|
||||||
#Report Bugs here: https://github.com/acmesh-official/acme.sh
|
#Report Bugs here: https://github.com/acmesh-official/acme.sh
|
||||||
# or here... https://github.com/acmesh-official/acme.sh/issues/2851
|
# or here... https://github.com/acmesh-official/acme.sh/issues/2851
|
||||||
@ -40,8 +40,35 @@ dns_1984hosting_add() {
|
|||||||
_debug _sub_domain "$_sub_domain"
|
_debug _sub_domain "$_sub_domain"
|
||||||
_debug _domain "$_domain"
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
_1984hosting_add_txt_record "$_domain" "$_sub_domain" "$txtvalue"
|
_debug "Add TXT record $fulldomain with value '$txtvalue'"
|
||||||
return $?
|
value="$(printf '%s' "$txtvalue" | _url_encode)"
|
||||||
|
url="https://management.1984hosting.com/domains/entry/"
|
||||||
|
|
||||||
|
postdata="entry=new"
|
||||||
|
postdata="$postdata&type=TXT"
|
||||||
|
postdata="$postdata&ttl=3600"
|
||||||
|
postdata="$postdata&zone=$_domain"
|
||||||
|
postdata="$postdata&host=$_sub_domain"
|
||||||
|
postdata="$postdata&rdata=%22$value%22"
|
||||||
|
_debug2 postdata "$postdata"
|
||||||
|
|
||||||
|
_authpost "$postdata" "$url"
|
||||||
|
response="$(echo "$_response" | _normalizeJson)"
|
||||||
|
_debug2 response "$response"
|
||||||
|
|
||||||
|
if _contains "$response" '"haserrors": true'; then
|
||||||
|
_err "1984Hosting failed to add TXT record for $_sub_domain bad RC from _post"
|
||||||
|
return 1
|
||||||
|
elif _contains "$response" "<html>"; then
|
||||||
|
_err "1984Hosting failed to add TXT record for $_sub_domain. Check $HTTP_HEADER file"
|
||||||
|
return 1
|
||||||
|
elif _contains "$response" '"auth": false'; then
|
||||||
|
_err "1984Hosting failed to add TXT record for $_sub_domain. Invalid or expired cookie"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_info "Added acme challenge TXT record for $fulldomain at 1984Hosting"
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
#Usage: fulldomain txtvalue
|
#Usage: fulldomain txtvalue
|
||||||
@ -67,57 +94,10 @@ dns_1984hosting_rm() {
|
|||||||
_debug _sub_domain "$_sub_domain"
|
_debug _sub_domain "$_sub_domain"
|
||||||
_debug _domain "$_domain"
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
_1984hosting_delete_txt_record "$_domain" "$_sub_domain"
|
|
||||||
return $?
|
|
||||||
}
|
|
||||||
|
|
||||||
#################### Private functions below ##################################
|
|
||||||
|
|
||||||
# usage _1984hosting_add_txt_record domain subdomain value
|
|
||||||
# returns 0 success
|
|
||||||
_1984hosting_add_txt_record() {
|
|
||||||
_debug "Add TXT record $1 with value '$3'"
|
|
||||||
domain="$1"
|
|
||||||
subdomain="$2"
|
|
||||||
value="$(printf '%s' "$3" | _url_encode)"
|
|
||||||
url="https://management.1984hosting.com/domains/entry/"
|
|
||||||
|
|
||||||
postdata="entry=new"
|
|
||||||
postdata="$postdata&type=TXT"
|
|
||||||
postdata="$postdata&ttl=3600"
|
|
||||||
postdata="$postdata&zone=$domain"
|
|
||||||
postdata="$postdata&host=$subdomain"
|
|
||||||
postdata="$postdata&rdata=%22$value%22"
|
|
||||||
_debug2 postdata "$postdata"
|
|
||||||
|
|
||||||
_authpost "$postdata" "$url"
|
|
||||||
response="$(echo "$_response" | _normalizeJson)"
|
|
||||||
_debug2 response "$response"
|
|
||||||
|
|
||||||
if _contains "$response" '"haserrors": true'; then
|
|
||||||
_err "1984Hosting failed to add TXT record for $subdomain bad RC from _post"
|
|
||||||
return 1
|
|
||||||
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
|
|
||||||
_err "1984Hosting failed to add TXT record for $subdomain. Invalid or expired cookie"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
_info "Added acme challenge TXT record for $fulldomain at 1984Hosting"
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# usage _1984hosting_delete_txt_record entry_id
|
|
||||||
# returns 0 success
|
|
||||||
_1984hosting_delete_txt_record() {
|
|
||||||
_debug "Delete $fulldomain TXT record"
|
_debug "Delete $fulldomain TXT record"
|
||||||
domain="$1"
|
|
||||||
subdomain="$2"
|
|
||||||
url="https://management.1984hosting.com/domains"
|
url="https://management.1984hosting.com/domains"
|
||||||
|
|
||||||
_htmlget "$url" "$domain"
|
_htmlget "$url" "$_domain"
|
||||||
_debug2 _response "$_response"
|
_debug2 _response "$_response"
|
||||||
zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+')"
|
zone_id="$(echo "$_response" | _egrep_o 'zone\/[0-9]+')"
|
||||||
_debug2 zone_id "$zone_id"
|
_debug2 zone_id "$zone_id"
|
||||||
@ -126,7 +106,7 @@ _1984hosting_delete_txt_record() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_htmlget "$url/$zone_id" "$subdomain"
|
_htmlget "$url/$zone_id" "$_sub_domain"
|
||||||
_debug2 _response "$_response"
|
_debug2 _response "$_response"
|
||||||
entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')"
|
entry_id="$(echo "$_response" | _egrep_o 'entry_[0-9]+' | sed 's/entry_//')"
|
||||||
_debug2 entry_id "$entry_id"
|
_debug2 entry_id "$entry_id"
|
||||||
@ -148,6 +128,8 @@ _1984hosting_delete_txt_record() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#################### Private functions below ##################################
|
||||||
|
|
||||||
# usage: _1984hosting_login username password
|
# usage: _1984hosting_login username password
|
||||||
# returns 0 success
|
# returns 0 success
|
||||||
_1984hosting_login() {
|
_1984hosting_login() {
|
||||||
@ -167,7 +149,7 @@ _1984hosting_login() {
|
|||||||
response="$(echo "$response" | _normalizeJson)"
|
response="$(echo "$response" | _normalizeJson)"
|
||||||
_debug2 response "$response"
|
_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 ';')"
|
One984HOSTING_COOKIE="$(grep -i '^set-cookie:' "$HTTP_HEADER" | _tail_n 1 | _egrep_o 'sessionid=[^;]*;' | tr -d ';')"
|
||||||
export One984HOSTING_COOKIE
|
export One984HOSTING_COOKIE
|
||||||
_saveaccountconf_mutable One984HOSTING_COOKIE "$One984HOSTING_COOKIE"
|
_saveaccountconf_mutable One984HOSTING_COOKIE "$One984HOSTING_COOKIE"
|
||||||
@ -196,7 +178,7 @@ _check_cookie() {
|
|||||||
|
|
||||||
_authget "https://management.1984hosting.com/accounts/loginstatus/"
|
_authget "https://management.1984hosting.com/accounts/loginstatus/"
|
||||||
response="$(echo "$_response" | _normalizeJson)"
|
response="$(echo "$_response" | _normalizeJson)"
|
||||||
if [ "$_response" = '{"ok": true}' ]; then
|
if _contains "$response" '"ok": true'; then
|
||||||
_debug "Cached cookie still valid"
|
_debug "Cached cookie still valid"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
150
dnsapi/dns_anx.sh
Normal file
150
dnsapi/dns_anx.sh
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# Anexia CloudDNS acme.sh hook
|
||||||
|
# Author: MA
|
||||||
|
|
||||||
|
#ANX_Token="xxxx"
|
||||||
|
|
||||||
|
ANX_API='https://engine.anexia-it.com/api/clouddns/v1'
|
||||||
|
|
||||||
|
######## Public functions #####################
|
||||||
|
|
||||||
|
dns_anx_add() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
_info "Using ANX CDNS API"
|
||||||
|
|
||||||
|
ANX_Token="${ANX_Token:-$(_readaccountconf_mutable ANX_Token)}"
|
||||||
|
_debug fulldomain "$fulldomain"
|
||||||
|
_debug txtvalue "$txtvalue"
|
||||||
|
|
||||||
|
if [ "$ANX_Token" ]; then
|
||||||
|
_saveaccountconf_mutable ANX_Token "$ANX_Token"
|
||||||
|
else
|
||||||
|
_err "You didn't specify a ANEXIA Engine API token."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug "First detect the root zone"
|
||||||
|
if ! _get_root "$fulldomain"; then
|
||||||
|
_err "invalid domain"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Always add records, wildcard need two records with the same name
|
||||||
|
_anx_rest POST "zone.json/${_domain}/records" "{\"name\":\"$_sub_domain\",\"type\":\"TXT\",\"rdata\":\"$txtvalue\"}"
|
||||||
|
if _contains "$response" "$txtvalue"; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_anx_rm() {
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
_info "Using ANX CDNS API"
|
||||||
|
|
||||||
|
ANX_Token="${ANX_Token:-$(_readaccountconf_mutable ANX_Token)}"
|
||||||
|
|
||||||
|
_debug fulldomain "$fulldomain"
|
||||||
|
_debug txtvalue "$txtvalue"
|
||||||
|
|
||||||
|
_debug "First detect the root zone"
|
||||||
|
if ! _get_root "$fulldomain"; then
|
||||||
|
_err "invalid domain"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_get_record_id
|
||||||
|
|
||||||
|
if _is_uuid "$_record_id"; then
|
||||||
|
if ! _anx_rest DELETE "zone.json/${_domain}/records/$_record_id"; then
|
||||||
|
_err "Delete record"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
_info "No record found."
|
||||||
|
fi
|
||||||
|
echo "$response" | tr -d " " | grep \"status\":\"OK\" >/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
#################### Private functions below ##################################
|
||||||
|
|
||||||
|
_is_uuid() {
|
||||||
|
pattern='^\{?[A-Z0-9a-z]{8}-[A-Z0-9a-z]{4}-[A-Z0-9a-z]{4}-[A-Z0-9a-z]{4}-[A-Z0-9a-z]{12}\}?$'
|
||||||
|
if echo "$1" | _egrep_o "$pattern" >/dev/null; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_get_record_id() {
|
||||||
|
_debug subdomain "$_sub_domain"
|
||||||
|
_debug domain "$_domain"
|
||||||
|
|
||||||
|
if _anx_rest GET "zone.json/${_domain}/records?name=$_sub_domain&type=TXT"; then
|
||||||
|
_debug response "$response"
|
||||||
|
if _contains "$response" "\"name\":\"$_sub_domain\"" >/dev/null; then
|
||||||
|
_record_id=$(printf "%s\n" "$response" | _egrep_o "\[.\"identifier\":\"[^\"]*\"" | head -n 1 | cut -d : -f 2 | tr -d \")
|
||||||
|
else
|
||||||
|
_record_id=''
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
_err "Search existing record"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_anx_rest() {
|
||||||
|
m=$1
|
||||||
|
ep="$2"
|
||||||
|
data="$3"
|
||||||
|
_debug "$ep"
|
||||||
|
|
||||||
|
export _H1="Content-Type: application/json"
|
||||||
|
export _H2="Authorization: Token $ANX_Token"
|
||||||
|
|
||||||
|
if [ "$m" != "GET" ]; then
|
||||||
|
_debug data "$data"
|
||||||
|
response="$(_post "$data" "${ANX_API}/$ep" "" "$m")"
|
||||||
|
else
|
||||||
|
response="$(_get "${ANX_API}/$ep")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# shellcheck disable=SC2181
|
||||||
|
if [ "$?" != "0" ]; then
|
||||||
|
_err "error $ep"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug response "$response"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_get_root() {
|
||||||
|
domain=$1
|
||||||
|
i=1
|
||||||
|
p=1
|
||||||
|
|
||||||
|
_anx_rest GET "zone.json"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
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)
|
||||||
|
_domain=$h
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
p=$i
|
||||||
|
i=$(_math "$i" + 1)
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
@ -222,10 +222,10 @@ _use_instance_role() {
|
|||||||
|
|
||||||
_use_metadata() {
|
_use_metadata() {
|
||||||
_aws_creds="$(
|
_aws_creds="$(
|
||||||
_get "$1" "" 1 \
|
_get "$1" "" 1 |
|
||||||
| _normalizeJson \
|
_normalizeJson |
|
||||||
| tr '{,}' '\n' \
|
tr '{,}' '\n' |
|
||||||
| while read -r _line; do
|
while read -r _line; do
|
||||||
_key="$(echo "${_line%%:*}" | tr -d '"')"
|
_key="$(echo "${_line%%:*}" | tr -d '"')"
|
||||||
_value="${_line#*:}"
|
_value="${_line#*:}"
|
||||||
_debug3 "_key" "$_key"
|
_debug3 "_key" "$_key"
|
||||||
@ -235,8 +235,8 @@ _use_metadata() {
|
|||||||
SecretAccessKey) echo "AWS_SECRET_ACCESS_KEY=$_value" ;;
|
SecretAccessKey) echo "AWS_SECRET_ACCESS_KEY=$_value" ;;
|
||||||
Token) echo "AWS_SESSION_TOKEN=$_value" ;;
|
Token) echo "AWS_SESSION_TOKEN=$_value" ;;
|
||||||
esac
|
esac
|
||||||
done \
|
done |
|
||||||
| paste -sd' ' -
|
paste -sd' ' -
|
||||||
)"
|
)"
|
||||||
_secure_debug "_aws_creds" "$_aws_creds"
|
_secure_debug "_aws_creds" "$_aws_creds"
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ dns_azure_rm() {
|
|||||||
_azure_rest GET "$acmeRecordURI" "" "$accesstoken"
|
_azure_rest GET "$acmeRecordURI" "" "$accesstoken"
|
||||||
timestamp="$(_time)"
|
timestamp="$(_time)"
|
||||||
if [ "$_code" = "200" ]; then
|
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=""
|
values=""
|
||||||
comma=""
|
comma=""
|
||||||
for v in $vlist; do
|
for v in $vlist; do
|
||||||
@ -220,7 +220,7 @@ _azure_rest() {
|
|||||||
export _H2="accept: application/json"
|
export _H2="accept: application/json"
|
||||||
export _H3="Content-Type: application/json"
|
export _H3="Content-Type: application/json"
|
||||||
# clear headers from previous request to avoid getting wrong http code on timeouts
|
# clear headers from previous request to avoid getting wrong http code on timeouts
|
||||||
:>"$HTTP_HEADER"
|
: >"$HTTP_HEADER"
|
||||||
_debug "$ep"
|
_debug "$ep"
|
||||||
if [ "$m" != "GET" ]; then
|
if [ "$m" != "GET" ]; then
|
||||||
_secure_debug2 "data $data"
|
_secure_debug2 "data $data"
|
||||||
|
@ -69,7 +69,7 @@ dns_cloudns_rm() {
|
|||||||
for i in $(echo "$response" | tr '{' "\n" | grep "$record"); do
|
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')
|
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 zone "$zone"
|
||||||
_debug host "$host"
|
_debug host "$host"
|
||||||
_debug record "$record"
|
_debug record "$record"
|
||||||
@ -91,7 +91,7 @@ dns_cloudns_rm() {
|
|||||||
|
|
||||||
#################### Private functions below ##################################
|
#################### Private functions below ##################################
|
||||||
_dns_cloudns_init_check() {
|
_dns_cloudns_init_check() {
|
||||||
if [ ! -z "$CLOUDNS_INIT_CHECK_COMPLETED" ]; then
|
if [ -n "$CLOUDNS_INIT_CHECK_COMPLETED" ]; then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ _dns_cloudns_http_api_call() {
|
|||||||
_debug CLOUDNS_SUB_AUTH_ID "$CLOUDNS_SUB_AUTH_ID"
|
_debug CLOUDNS_SUB_AUTH_ID "$CLOUDNS_SUB_AUTH_ID"
|
||||||
_debug CLOUDNS_AUTH_PASSWORD "$CLOUDNS_AUTH_PASSWORD"
|
_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"
|
auth_user="sub-auth-id=$CLOUDNS_SUB_AUTH_ID"
|
||||||
else
|
else
|
||||||
auth_user="auth-id=$CLOUDNS_AUTH_ID"
|
auth_user="auth-id=$CLOUDNS_AUTH_ID"
|
||||||
|
@ -115,9 +115,9 @@ dns_conoha_rm() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
record_id=$(printf "%s" "$response" | _egrep_o '{[^}]*}' \
|
record_id=$(printf "%s" "$response" | _egrep_o '{[^}]*}' |
|
||||||
| grep '"type":"TXT"' | grep "\"data\":\"$txtvalue\"" | _egrep_o "\"id\":\"[^\"]*\"" \
|
grep '"type":"TXT"' | grep "\"data\":\"$txtvalue\"" | _egrep_o "\"id\":\"[^\"]*\"" |
|
||||||
| _head_n 1 | cut -d : -f 2 | tr -d \")
|
_head_n 1 | cut -d : -f 2 | tr -d \")
|
||||||
if [ -z "$record_id" ]; then
|
if [ -z "$record_id" ]; then
|
||||||
_err "Can not get record id to remove."
|
_err "Can not get record id to remove."
|
||||||
return 1
|
return 1
|
||||||
|
@ -18,23 +18,23 @@
|
|||||||
########
|
########
|
||||||
|
|
||||||
dns_cyon_add() {
|
dns_cyon_add() {
|
||||||
_cyon_load_credentials \
|
_cyon_load_credentials &&
|
||||||
&& _cyon_load_parameters "$@" \
|
_cyon_load_parameters "$@" &&
|
||||||
&& _cyon_print_header "add" \
|
_cyon_print_header "add" &&
|
||||||
&& _cyon_login \
|
_cyon_login &&
|
||||||
&& _cyon_change_domain_env \
|
_cyon_change_domain_env &&
|
||||||
&& _cyon_add_txt \
|
_cyon_add_txt &&
|
||||||
&& _cyon_logout
|
_cyon_logout
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_cyon_rm() {
|
dns_cyon_rm() {
|
||||||
_cyon_load_credentials \
|
_cyon_load_credentials &&
|
||||||
&& _cyon_load_parameters "$@" \
|
_cyon_load_parameters "$@" &&
|
||||||
&& _cyon_print_header "delete" \
|
_cyon_print_header "delete" &&
|
||||||
&& _cyon_login \
|
_cyon_login &&
|
||||||
&& _cyon_change_domain_env \
|
_cyon_change_domain_env &&
|
||||||
&& _cyon_delete_txt \
|
_cyon_delete_txt &&
|
||||||
&& _cyon_logout
|
_cyon_logout
|
||||||
}
|
}
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
@ -66,7 +66,7 @@ _cyon_load_credentials() {
|
|||||||
_debug "Save credentials to account.conf"
|
_debug "Save credentials to account.conf"
|
||||||
_saveaccountconf CY_Username "${CY_Username}"
|
_saveaccountconf CY_Username "${CY_Username}"
|
||||||
_saveaccountconf CY_Password_B64 "$CY_Password_B64"
|
_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"
|
_saveaccountconf CY_OTP_Secret "$CY_OTP_Secret"
|
||||||
else
|
else
|
||||||
_clearaccountconf CY_OTP_Secret
|
_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.
|
# 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?
|
# 2FA authentication with OTP?
|
||||||
if [ ! -z "${CY_OTP_Secret}" ]; then
|
if [ -n "${CY_OTP_Secret}" ]; then
|
||||||
_info " - Authorising with OTP code..."
|
_info " - Authorising with OTP code..."
|
||||||
|
|
||||||
if ! _exists oathtool; then
|
if ! _exists oathtool; then
|
||||||
|
@ -122,12 +122,12 @@ dns_dgon_rm() {
|
|||||||
## check for what we are looking for: "type":"A","name":"$_sub_domain"
|
## 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\"")"
|
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
|
## we found records
|
||||||
rec_ids="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")"
|
rec_ids="$(echo "$record" | _egrep_o "id\"\s*\:\s*\"*[0-9]+" | _egrep_o "[0-9]+")"
|
||||||
_debug rec_ids "$rec_ids"
|
_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
|
echo "$rec_ids" | while IFS= read -r rec_id; do
|
||||||
## delete the record
|
## delete the record
|
||||||
## delete URL for removing the one we dont want
|
## 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
|
## we got part of a domain back - grep it out
|
||||||
found="$(echo "$domain_list" | _egrep_o "\"name\"\s*\:\s*\"$_domain\"")"
|
found="$(echo "$domain_list" | _egrep_o "\"name\"\s*\:\s*\"$_domain\"")"
|
||||||
## check if it exists
|
## check if it exists
|
||||||
if [ ! -z "$found" ]; then
|
if [ -n "$found" ]; then
|
||||||
## exists - exit loop returning the parts
|
## exists - exit loop returning the parts
|
||||||
sub_point=$(_math $i - 1)
|
sub_point=$(_math $i - 1)
|
||||||
_sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-"$sub_point")
|
_sub_domain=$(printf "%s" "$fulldomain" | cut -d . -f 1-"$sub_point")
|
||||||
|
@ -67,14 +67,14 @@ _dns_do_list_rrs() {
|
|||||||
_err "getRRList origin ${_domain} failed"
|
_err "getRRList origin ${_domain} failed"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
_rr_list="$(echo "${response}" \
|
_rr_list="$(echo "${response}" |
|
||||||
| tr -d "\n\r\t" \
|
tr -d "\n\r\t" |
|
||||||
| sed -e 's/<item xsi:type="ns2:Map">/\n/g' \
|
sed -e 's/<item xsi:type="ns2:Map">/\n/g' |
|
||||||
| grep ">$(_regexcape "$fulldomain")</value>" \
|
grep ">$(_regexcape "$fulldomain")</value>" |
|
||||||
| sed -e 's/<\/item>/\n/g' \
|
sed -e 's/<\/item>/\n/g' |
|
||||||
| grep '>id</key><value' \
|
grep '>id</key><value' |
|
||||||
| _egrep_o '>[0-9]{1,16}<' \
|
_egrep_o '>[0-9]{1,16}<' |
|
||||||
| tr -d '><')"
|
tr -d '><')"
|
||||||
[ "${_rr_list}" ]
|
[ "${_rr_list}" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,10 +120,10 @@ _get_root() {
|
|||||||
i=1
|
i=1
|
||||||
|
|
||||||
_dns_do_soap getDomainList
|
_dns_do_soap getDomainList
|
||||||
_all_domains="$(echo "${response}" \
|
_all_domains="$(echo "${response}" |
|
||||||
| tr -d "\n\r\t " \
|
tr -d "\n\r\t " |
|
||||||
| _egrep_o 'domain</key><value[^>]+>[^<]+' \
|
_egrep_o 'domain</key><value[^>]+>[^<]+' |
|
||||||
| sed -e 's/^domain<\/key><value[^>]*>//g')"
|
sed -e 's/^domain<\/key><value[^>]*>//g')"
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||||
|
@ -112,16 +112,21 @@ _duckdns_rest() {
|
|||||||
param="$2"
|
param="$2"
|
||||||
_debug param "$param"
|
_debug param "$param"
|
||||||
url="$DuckDNS_API?$param"
|
url="$DuckDNS_API?$param"
|
||||||
|
if [ "$DEBUG" -gt 0 ]; then
|
||||||
|
url="$url&verbose=true"
|
||||||
|
fi
|
||||||
_debug url "$url"
|
_debug url "$url"
|
||||||
|
|
||||||
# DuckDNS uses GET to update domain info
|
# DuckDNS uses GET to update domain info
|
||||||
if [ "$method" = "GET" ]; then
|
if [ "$method" = "GET" ]; then
|
||||||
response="$(_get "$url")"
|
response="$(_get "$url")"
|
||||||
|
_debug2 response "$response"
|
||||||
|
if [ "$DEBUG" -gt 0 ] && _contains "$response" "UPDATED" && _contains "$response" "OK"; then
|
||||||
|
response="OK"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
_err "Unsupported method"
|
_err "Unsupported method"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_debug2 response "$response"
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -1,35 +1,41 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
#Author StefanAbl
|
#Author StefanAbl
|
||||||
#Usage specify a private keyfile to use with dynv6 'export KEY="path/to/keyfile"'
|
#Usage specify a private keyfile to use with dynv6 'export KEY="path/to/keyfile"'
|
||||||
|
#or use the HTTP REST API by by specifying a token 'export DYNV6_TOKEN="value"
|
||||||
#if no keyfile is specified, you will be asked if you want to create one in /home/$USER/.ssh/dynv6 and /home/$USER/.ssh/dynv6.pub
|
#if no keyfile is specified, you will be asked if you want to create one in /home/$USER/.ssh/dynv6 and /home/$USER/.ssh/dynv6.pub
|
||||||
|
|
||||||
|
dynv6_api="https://dynv6.com/api/v2"
|
||||||
######## Public functions #####################
|
######## Public functions #####################
|
||||||
# Please Read this guide first: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide
|
# Please Read this guide first: https://github.com/Neilpang/acme.sh/wiki/DNS-API-Dev-Guide
|
||||||
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
#Usage: dns_dynv6_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
dns_dynv6_add() {
|
dns_dynv6_add() {
|
||||||
fulldomain=$1
|
fulldomain=$1
|
||||||
txtvalue=$2
|
txtvalue=$2
|
||||||
_info "Using dynv6 api"
|
_info "Using dynv6 api"
|
||||||
_debug fulldomain "$fulldomain"
|
_debug fulldomain "$fulldomain"
|
||||||
_debug txtvalue "$txtvalue"
|
_debug txtvalue "$txtvalue"
|
||||||
_get_keyfile
|
_get_authentication
|
||||||
_info "using keyfile $dynv6_keyfile"
|
if [ "$dynv6_token" ]; then
|
||||||
_get_domain "$fulldomain"
|
_dns_dynv6_add_http
|
||||||
|
return $?
|
||||||
|
else
|
||||||
|
_info "using key file $dynv6_keyfile"
|
||||||
_your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)"
|
_your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)"
|
||||||
if ! _contains "$_your_hosts" "$_host"; then
|
if ! _get_domain "$fulldomain" "$_your_hosts"; then
|
||||||
_debug "The host is $_host and the record $_record"
|
_err "Host not found on your account"
|
||||||
_debug "Dynv6 returned $_your_hosts"
|
|
||||||
_err "The host $_host does not exist on your dynv6 account"
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
_debug "found host on your account"
|
_debug "found host on your account"
|
||||||
returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")"
|
returnval="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts \""$_host"\" records set \""$_record"\" txt data \""$txtvalue"\")"
|
||||||
_debug "Dynv6 returend this after record was added: $returnval"
|
_debug "Dynv6 returned this after record was added: $returnval"
|
||||||
if _contains "$returnval" "created"; then
|
if _contains "$returnval" "created"; then
|
||||||
return 0
|
return 0
|
||||||
elif _contains "$returnval" "updated"; then
|
elif _contains "$returnval" "updated"; then
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
_err "Something went wrong! it does not seem like the record was added succesfully"
|
_err "Something went wrong! it does not seem like the record was added successfully"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
return 1
|
return 1
|
||||||
@ -39,28 +45,29 @@ dns_dynv6_add() {
|
|||||||
dns_dynv6_rm() {
|
dns_dynv6_rm() {
|
||||||
fulldomain=$1
|
fulldomain=$1
|
||||||
txtvalue=$2
|
txtvalue=$2
|
||||||
_info "Using dynv6 api"
|
_info "Using dynv6 API"
|
||||||
_debug fulldomain "$fulldomain"
|
_debug fulldomain "$fulldomain"
|
||||||
_debug txtvalue "$txtvalue"
|
_debug txtvalue "$txtvalue"
|
||||||
_get_keyfile
|
_get_authentication
|
||||||
_info "using keyfile $dynv6_keyfile"
|
if [ "$dynv6_token" ]; then
|
||||||
_get_domain "$fulldomain"
|
_dns_dynv6_rm_http
|
||||||
|
return $?
|
||||||
|
else
|
||||||
|
_info "using key file $dynv6_keyfile"
|
||||||
_your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)"
|
_your_hosts="$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts)"
|
||||||
if ! _contains "$_your_hosts" "$_host"; then
|
if ! _get_domain "$fulldomain" "$_your_hosts"; then
|
||||||
_debug "The host is $_host and the record $_record"
|
_err "Host not found on your account"
|
||||||
_debug "Dynv6 returned $_your_hosts"
|
|
||||||
_err "The host $_host does not exist on your dynv6 account"
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
_debug "found host on your account"
|
_debug "found host on your account"
|
||||||
_info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)"
|
_info "$(ssh -i "$dynv6_keyfile" api@dynv6.com hosts "\"$_host\"" records del "\"$_record\"" txt)"
|
||||||
return 0
|
return 0
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
#################### Private functions below ##################################
|
#################### Private functions below ##################################
|
||||||
#Usage: No Input required
|
#Usage: No Input required
|
||||||
#returns
|
#returns
|
||||||
#dynv6_keyfile the path to the new keyfile that has been generated
|
#dynv6_keyfile the path to the new key file that has been generated
|
||||||
_generate_new_key() {
|
_generate_new_key() {
|
||||||
dynv6_keyfile="$(eval echo ~"$USER")/.ssh/dynv6"
|
dynv6_keyfile="$(eval echo ~"$USER")/.ssh/dynv6"
|
||||||
_info "Path to key file used: $dynv6_keyfile"
|
_info "Path to key file used: $dynv6_keyfile"
|
||||||
@ -72,45 +79,53 @@ _generate_new_key() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
#Usage: _acme-challenge.www.example.dynv6.net
|
|
||||||
|
#Usage: _acme-challenge.www.example.dynv6.net "$_your_hosts"
|
||||||
|
#where _your_hosts is the output of ssh -i ~/.ssh/dynv6.pub api@dynv6.com hosts
|
||||||
#returns
|
#returns
|
||||||
#_host= example.dynv6.net
|
#_host= example.dynv6.net
|
||||||
#_record=_acme-challenge.www
|
#_record=_acme-challenge.www
|
||||||
#aborts if not a valid domain
|
#aborts if not a valid domain
|
||||||
_get_domain() {
|
_get_domain() {
|
||||||
|
#_your_hosts="$(ssh -i ~/.ssh/dynv6.pub api@dynv6.com hosts)"
|
||||||
_full_domain="$1"
|
_full_domain="$1"
|
||||||
_debug "getting domain for $_full_domain"
|
_your_hosts="$2"
|
||||||
if ! _contains "$_full_domain" 'dynv6.net' && ! _contains "$_full_domain" 'dns.army' && ! _contains "$_full_domain" 'dns.navy'; then
|
|
||||||
_err "The hosts does not seem to be a dynv6 host"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
_record="${_full_domain%.*}"
|
|
||||||
_record="${_record%.*}"
|
|
||||||
_record="${_record%.*}"
|
|
||||||
_debug "The record we are ging to use is $_record"
|
|
||||||
_host="$_full_domain"
|
|
||||||
while [ "$(echo "$_host" | grep -o '\.' | wc -l)" != "2" ]; do
|
|
||||||
_host="${_host#*.}"
|
|
||||||
done
|
|
||||||
_debug "And the host is $_host"
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
_your_hosts="$(echo "$_your_hosts" | awk '/\./ {print $1}')"
|
||||||
|
for l in $_your_hosts; do
|
||||||
|
#echo "host: $l"
|
||||||
|
if test "${_full_domain#*$l}" != "$_full_domain"; then
|
||||||
|
_record="${_full_domain%.$l}"
|
||||||
|
_host=$l
|
||||||
|
_debug "The host is $_host and the record $_record"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
_err "Either their is no such host on your dnyv6 account or it cannot be accessed with this key"
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Usage: No input required
|
# Usage: No input required
|
||||||
#returns
|
#returns
|
||||||
#dynv6_keyfile path to the key that will be used
|
#dynv6_keyfile path to the key that will be used
|
||||||
_get_keyfile() {
|
_get_authentication() {
|
||||||
_debug "get keyfile method called"
|
dynv6_token="${DYNV6_TOKEN:-$(_readaccountconf_mutable dynv6_token)}"
|
||||||
|
if [ "$dynv6_token" ]; then
|
||||||
|
_debug "Found HTTP Token. Going to use the HTTP API and not the SSH API"
|
||||||
|
if [ "$DYNV6_TOKEN" ]; then
|
||||||
|
_saveaccountconf_mutable dynv6_token "$dynv6_token"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
_debug "no HTTP token found. Looking for an SSH key"
|
||||||
dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}"
|
dynv6_keyfile="${dynv6_keyfile:-$(_readaccountconf_mutable dynv6_keyfile)}"
|
||||||
_debug Your key is "$dynv6_keyfile"
|
_debug "Your key is $dynv6_keyfile"
|
||||||
if [ -z "$dynv6_keyfile" ]; then
|
if [ -z "$dynv6_keyfile" ]; then
|
||||||
if [ -z "$KEY" ]; then
|
if [ -z "$KEY" ]; then
|
||||||
_err "You did not specify a key to use with dynv6"
|
_err "You did not specify a key to use with dynv6"
|
||||||
_info "Creating new dynv6 api key to add to dynv6.com"
|
_info "Creating new dynv6 API key to add to dynv6.com"
|
||||||
_generate_new_key
|
_generate_new_key
|
||||||
_info "Please add this key to dynv6.com $(cat "$dynv6_keyfile.pub")"
|
_info "Please add this key to dynv6.com $(cat "$dynv6_keyfile.pub")"
|
||||||
_info "Hit Enter to contiue"
|
_info "Hit Enter to continue"
|
||||||
read -r _
|
read -r _
|
||||||
#save the credentials to the account conf file.
|
#save the credentials to the account conf file.
|
||||||
else
|
else
|
||||||
@ -118,4 +133,153 @@ _get_keyfile() {
|
|||||||
fi
|
fi
|
||||||
_saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile"
|
_saveaccountconf_mutable dynv6_keyfile "$dynv6_keyfile"
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_dns_dynv6_add_http() {
|
||||||
|
_debug "Got HTTP token form _get_authentication method. Going to use the HTTP API"
|
||||||
|
if ! _get_zone_id "$fulldomain"; then
|
||||||
|
_err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_get_zone_name "$_zone_id"
|
||||||
|
record="${fulldomain%%.$_zone_name}"
|
||||||
|
_set_record TXT "$record" "$txtvalue"
|
||||||
|
if _contains "$response" "$txtvalue"; then
|
||||||
|
_info "Successfully added record"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Something went wrong while adding the record"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_dns_dynv6_rm_http() {
|
||||||
|
_debug "Got HTTP token form _get_authentication method. Going to use the HTTP API"
|
||||||
|
if ! _get_zone_id "$fulldomain"; then
|
||||||
|
_err "Could not find a matching zone for $fulldomain. Maybe your HTTP Token is not authorized to access the zone"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_get_zone_name "$_zone_id"
|
||||||
|
record="${fulldomain%%.$_zone_name}"
|
||||||
|
_get_record_id "$_zone_id" "$record" "$txtvalue"
|
||||||
|
_del_record "$_zone_id" "$_record_id"
|
||||||
|
if [ -z "$response" ]; then
|
||||||
|
_info "Successfully deleted record"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Something went wrong while deleting the record"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#get the zoneid for a specifc record or zone
|
||||||
|
#usage: _get_zone_id §record
|
||||||
|
#where $record is the record to get the id for
|
||||||
|
#returns _zone_id the id of the zone
|
||||||
|
_get_zone_id() {
|
||||||
|
record="$1"
|
||||||
|
_debug "getting zone id for $record"
|
||||||
|
_dynv6_rest GET zones
|
||||||
|
|
||||||
|
zones="$(echo "$response" | tr '}' '\n' | tr ',' '\n' | grep name | sed 's/\[//g' | tr -d '{' | tr -d '"')"
|
||||||
|
#echo $zones
|
||||||
|
|
||||||
|
selected=""
|
||||||
|
for z in $zones; do
|
||||||
|
z="${z#name:}"
|
||||||
|
_debug zone: "$z"
|
||||||
|
if _contains "$record" "$z"; then
|
||||||
|
_debug "$z found in $record"
|
||||||
|
selected="$z"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ -z "$selected" ]; then
|
||||||
|
_err "no zone found"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
zone_id="$(echo "$response" | tr '}' '\n' | grep "$selected" | tr ',' '\n' | grep id | tr -d '"')"
|
||||||
|
_zone_id="${zone_id#id:}"
|
||||||
|
_debug "zone id: $_zone_id"
|
||||||
|
}
|
||||||
|
|
||||||
|
_get_zone_name() {
|
||||||
|
_zone_id="$1"
|
||||||
|
_dynv6_rest GET zones/"$_zone_id"
|
||||||
|
_zone_name="$(echo "$response" | tr ',' '\n' | tr -d '{' | grep name | tr -d '"')"
|
||||||
|
_zone_name="${_zone_name#name:}"
|
||||||
|
}
|
||||||
|
|
||||||
|
#usaage _get_record_id $zone_id $record
|
||||||
|
# where zone_id is thevalue returned by _get_zone_id
|
||||||
|
# and record ist in the form _acme.www for an fqdn of _acme.www.example.com
|
||||||
|
# returns _record_id
|
||||||
|
_get_record_id() {
|
||||||
|
_zone_id="$1"
|
||||||
|
record="$2"
|
||||||
|
value="$3"
|
||||||
|
_dynv6_rest GET "zones/$_zone_id/records"
|
||||||
|
if ! _get_record_id_from_response "$response"; then
|
||||||
|
_err "no such record $record found in zone $_zone_id"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_get_record_id_from_response() {
|
||||||
|
response="$1"
|
||||||
|
_record_id="$(echo "$response" | tr '}' '\n' | grep "\"name\":\"$record\"" | grep "\"data\":\"$value\"" | tr ',' '\n' | grep id | tr -d '"' | tr -d 'id:')"
|
||||||
|
#_record_id="${_record_id#id:}"
|
||||||
|
if [ -z "$_record_id" ]; then
|
||||||
|
_err "no such record: $record found in zone $_zone_id"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug "record id: $_record_id"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
#usage: _set_record TXT _acme_challenge.www longvalue 12345678
|
||||||
|
#zone id is optional can also be set as vairable bevor calling this method
|
||||||
|
_set_record() {
|
||||||
|
type="$1"
|
||||||
|
record="$2"
|
||||||
|
value="$3"
|
||||||
|
if [ "$4" ]; then
|
||||||
|
_zone_id="$4"
|
||||||
|
fi
|
||||||
|
data="{\"name\": \"$record\", \"data\": \"$value\", \"type\": \"$type\"}"
|
||||||
|
#data='{ "name": "acme.test.thorn.dynv6.net", "type": "A", "data": "192.168.0.1"}'
|
||||||
|
echo "$data"
|
||||||
|
#"{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}"
|
||||||
|
_dynv6_rest POST "zones/$_zone_id/records" "$data"
|
||||||
|
}
|
||||||
|
_del_record() {
|
||||||
|
_zone_id=$1
|
||||||
|
_record_id=$2
|
||||||
|
_dynv6_rest DELETE zones/"$_zone_id"/records/"$_record_id"
|
||||||
|
}
|
||||||
|
|
||||||
|
_dynv6_rest() {
|
||||||
|
m=$1 #method GET,POST,DELETE or PUT
|
||||||
|
ep="$2" #the endpoint
|
||||||
|
data="$3"
|
||||||
|
_debug "$ep"
|
||||||
|
|
||||||
|
token_trimmed=$(echo "$dynv6_token" | tr -d '"')
|
||||||
|
|
||||||
|
export _H1="Authorization: Bearer $token_trimmed"
|
||||||
|
export _H2="Content-Type: application/json"
|
||||||
|
|
||||||
|
if [ "$m" != "GET" ]; then
|
||||||
|
_debug data "$data"
|
||||||
|
response="$(_post "$data" "$dynv6_api/$ep" "" "$m")"
|
||||||
|
else
|
||||||
|
response="$(_get "$dynv6_api/$ep")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$?" != "0" ]; then
|
||||||
|
_err "error $ep"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug2 response "$response"
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -303,10 +303,10 @@ _freedns_domain_id() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
domain_id="$(echo "$htmlpage" | tr -d " \t\r\n\v\f" | sed 's/<tr>/@<tr>/g' | tr '@' '\n' \
|
domain_id="$(echo "$htmlpage" | tr -d " \t\r\n\v\f" | sed 's/<tr>/@<tr>/g' | tr '@' '\n' |
|
||||||
| grep "<td>$search_domain</td>\|<td>$search_domain(.*)</td>" \
|
grep "<td>$search_domain</td>\|<td>$search_domain(.*)</td>" |
|
||||||
| sed -n 's/.*\(edit\.php?edit_domain_id=[0-9a-zA-Z]*\).*/\1/p' \
|
sed -n 's/.*\(edit\.php?edit_domain_id=[0-9a-zA-Z]*\).*/\1/p' |
|
||||||
| cut -d = -f 2)"
|
cut -d = -f 2)"
|
||||||
# The above beauty extracts domain ID from the html page...
|
# The above beauty extracts domain ID from the html page...
|
||||||
# strip out all blank space and new lines. Then insert newlines
|
# strip out all blank space and new lines. Then insert newlines
|
||||||
# before each table row <tr>
|
# before each table row <tr>
|
||||||
@ -349,11 +349,11 @@ _freedns_data_id() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
data_id="$(echo "$htmlpage" | tr -d " \t\r\n\v\f" | sed 's/<tr>/@<tr>/g' | tr '@' '\n' \
|
data_id="$(echo "$htmlpage" | tr -d " \t\r\n\v\f" | sed 's/<tr>/@<tr>/g' | tr '@' '\n' |
|
||||||
| grep "<td[a-zA-Z=#]*>$record_type</td>" \
|
grep "<td[a-zA-Z=#]*>$record_type</td>" |
|
||||||
| grep "<ahref.*>$search_domain</a>" \
|
grep "<ahref.*>$search_domain</a>" |
|
||||||
| sed -n 's/.*\(edit\.php?data_id=[0-9a-zA-Z]*\).*/\1/p' \
|
sed -n 's/.*\(edit\.php?data_id=[0-9a-zA-Z]*\).*/\1/p' |
|
||||||
| cut -d = -f 2)"
|
cut -d = -f 2)"
|
||||||
# The above beauty extracts data ID from the html page...
|
# The above beauty extracts data ID from the html page...
|
||||||
# strip out all blank space and new lines. Then insert newlines
|
# strip out all blank space and new lines. Then insert newlines
|
||||||
# before each table row <tr>
|
# before each table row <tr>
|
||||||
|
@ -69,9 +69,9 @@ dns_gandi_livedns_rm() {
|
|||||||
|
|
||||||
_gandi_livedns_rest PUT \
|
_gandi_livedns_rest PUT \
|
||||||
"domains/$_domain/records/$_sub_domain/TXT" \
|
"domains/$_domain/records/$_sub_domain/TXT" \
|
||||||
"{\"rrset_ttl\": 300, \"rrset_values\": $_new_rrset_values}" \
|
"{\"rrset_ttl\": 300, \"rrset_values\": $_new_rrset_values}" &&
|
||||||
&& _contains "$response" '{"message": "DNS Record Created"}' \
|
_contains "$response" '{"message": "DNS Record Created"}' &&
|
||||||
&& _info "Removing record $(__green "success")"
|
_info "Removing record $(__green "success")"
|
||||||
}
|
}
|
||||||
|
|
||||||
#################### Private functions below ##################################
|
#################### Private functions below ##################################
|
||||||
@ -125,9 +125,9 @@ _dns_gandi_append_record() {
|
|||||||
fi
|
fi
|
||||||
_debug new_rrset_values "$_rrset_values"
|
_debug new_rrset_values "$_rrset_values"
|
||||||
_gandi_livedns_rest PUT "domains/$_domain/records/$sub_domain/TXT" \
|
_gandi_livedns_rest PUT "domains/$_domain/records/$sub_domain/TXT" \
|
||||||
"{\"rrset_ttl\": 300, \"rrset_values\": $_rrset_values}" \
|
"{\"rrset_ttl\": 300, \"rrset_values\": $_rrset_values}" &&
|
||||||
&& _contains "$response" '{"message": "DNS Record Created"}' \
|
_contains "$response" '{"message": "DNS Record Created"}' &&
|
||||||
&& _info "Adding record $(__green "success")"
|
_info "Adding record $(__green "success")"
|
||||||
}
|
}
|
||||||
|
|
||||||
_dns_gandi_existing_rrset_values() {
|
_dns_gandi_existing_rrset_values() {
|
||||||
@ -145,8 +145,8 @@ _dns_gandi_existing_rrset_values() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
_debug "Already has TXT record."
|
_debug "Already has TXT record."
|
||||||
_rrset_values=$(echo "$response" | _egrep_o 'rrset_values.*\[.*\]' \
|
_rrset_values=$(echo "$response" | _egrep_o 'rrset_values.*\[.*\]' |
|
||||||
| _egrep_o '\[".*\"]')
|
_egrep_o '\[".*\"]')
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,8 +78,8 @@ _dns_gcloud_execute_tr() {
|
|||||||
for i in $(seq 1 120); do
|
for i in $(seq 1 120); do
|
||||||
if gcloud dns record-sets changes list \
|
if gcloud dns record-sets changes list \
|
||||||
--zone="$managedZone" \
|
--zone="$managedZone" \
|
||||||
--filter='status != done' \
|
--filter='status != done' |
|
||||||
| grep -q '^.*'; then
|
grep -q '^.*'; then
|
||||||
_info "_dns_gcloud_execute_tr: waiting for transaction to be comitted ($i/120)..."
|
_info "_dns_gcloud_execute_tr: waiting for transaction to be comitted ($i/120)..."
|
||||||
sleep 5
|
sleep 5
|
||||||
else
|
else
|
||||||
@ -137,11 +137,11 @@ _dns_gcloud_find_zone() {
|
|||||||
# List domains and find the zone with the deepest sub-domain (in case of some levels of delegation)
|
# List domains and find the zone with the deepest sub-domain (in case of some levels of delegation)
|
||||||
if ! match=$(gcloud dns managed-zones list \
|
if ! match=$(gcloud dns managed-zones list \
|
||||||
--format="value(name, dnsName)" \
|
--format="value(name, dnsName)" \
|
||||||
--filter="$filter" \
|
--filter="$filter" |
|
||||||
| while read -r dnsName name; do
|
while read -r dnsName name; do
|
||||||
printf "%s\t%s\t%s\n" "$(echo "$name" | awk -F"." '{print NF-1}')" "$dnsName" "$name"
|
printf "%s\t%s\t%s\n" "$(echo "$name" | awk -F"." '{print NF-1}')" "$dnsName" "$name"
|
||||||
done \
|
done |
|
||||||
| sort -n -r | _head_n 1 | cut -f2,3 | grep '^.*'); then
|
sort -n -r | _head_n 1 | cut -f2,3 | grep '^.*'); then
|
||||||
_err "_dns_gcloud_find_zone: Can't find a matching managed zone! Perhaps wrong project or gcloud credentials?"
|
_err "_dns_gcloud_find_zone: Can't find a matching managed zone! Perhaps wrong project or gcloud credentials?"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
@ -101,8 +101,8 @@ dns_he_rm() {
|
|||||||
body="$body&hosted_dns_editzone=1"
|
body="$body&hosted_dns_editzone=1"
|
||||||
body="$body&hosted_dns_delrecord=1"
|
body="$body&hosted_dns_delrecord=1"
|
||||||
body="$body&hosted_dns_delconfirm=delete"
|
body="$body&hosted_dns_delconfirm=delete"
|
||||||
_post "$body" "https://dns.he.net/" \
|
_post "$body" "https://dns.he.net/" |
|
||||||
| grep '<div id="dns_status" onClick="hideThis(this);">Successfully removed record.</div>' \
|
grep '<div id="dns_status" onClick="hideThis(this);">Successfully removed record.</div>' \
|
||||||
>/dev/null
|
>/dev/null
|
||||||
exit_code="$?"
|
exit_code="$?"
|
||||||
if [ "$exit_code" -eq 0 ]; then
|
if [ "$exit_code" -eq 0 ]; then
|
||||||
|
@ -123,10 +123,10 @@ _find_record() {
|
|||||||
return 1
|
return 1
|
||||||
else
|
else
|
||||||
_record_id=$(
|
_record_id=$(
|
||||||
echo "$response" \
|
echo "$response" |
|
||||||
| grep -o "{[^\{\}]*\"name\":\"$_record_name\"[^\}]*}" \
|
grep -o "{[^\{\}]*\"name\":\"$_record_name\"[^\}]*}" |
|
||||||
| grep "\"value\":\"$_record_value\"" \
|
grep "\"value\":\"$_record_value\"" |
|
||||||
| while read -r record; do
|
while read -r record; do
|
||||||
# test for type and
|
# test for type and
|
||||||
if [ -n "$(echo "$record" | _egrep_o '"type":"TXT"')" ]; then
|
if [ -n "$(echo "$record" | _egrep_o '"type":"TXT"')" ]; then
|
||||||
echo "$record" | _egrep_o '"id":"[^"]*"' | cut -d : -f 2 | tr -d \"
|
echo "$record" | _egrep_o '"id":"[^"]*"' | cut -d : -f 2 | tr -d \"
|
||||||
|
199
dnsapi/dns_infomaniak.sh
Executable file
199
dnsapi/dns_infomaniak.sh
Executable file
@ -0,0 +1,199 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Infomaniak API integration
|
||||||
|
#
|
||||||
|
# To use this API you need visit the API dashboard of your account
|
||||||
|
# once logged into https://manager.infomaniak.com add /api/dashboard to the URL
|
||||||
|
#
|
||||||
|
# Please report bugs to
|
||||||
|
# https://github.com/acmesh-official/acme.sh/issues/3188
|
||||||
|
#
|
||||||
|
# Note: the URL looks like this:
|
||||||
|
# https://manager.infomaniak.com/v3/<account_id>/api/dashboard
|
||||||
|
# Then generate a token with the scope Domain
|
||||||
|
# this is given as an environment variable INFOMANIAK_API_TOKEN
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
# base variables
|
||||||
|
|
||||||
|
DEFAULT_INFOMANIAK_API_URL="https://api.infomaniak.com"
|
||||||
|
DEFAULT_INFOMANIAK_TTL=300
|
||||||
|
|
||||||
|
######## Public functions #####################
|
||||||
|
|
||||||
|
#Usage: dns_infomaniak_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
|
dns_infomaniak_add() {
|
||||||
|
|
||||||
|
INFOMANIAK_API_TOKEN="${INFOMANIAK_API_TOKEN:-$(_readaccountconf_mutable INFOMANIAK_API_TOKEN)}"
|
||||||
|
INFOMANIAK_API_URL="${INFOMANIAK_API_URL:-$(_readaccountconf_mutable INFOMANIAK_API_URL)}"
|
||||||
|
INFOMANIAK_TTL="${INFOMANIAK_TTL:-$(_readaccountconf_mutable INFOMANIAK_TTL)}"
|
||||||
|
|
||||||
|
if [ -z "$INFOMANIAK_API_TOKEN" ]; then
|
||||||
|
INFOMANIAK_API_TOKEN=""
|
||||||
|
_err "Please provide a valid Infomaniak API token in variable INFOMANIAK_API_TOKEN"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$INFOMANIAK_API_URL" ]; then
|
||||||
|
INFOMANIAK_API_URL="$DEFAULT_INFOMANIAK_API_URL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$INFOMANIAK_TTL" ]; then
|
||||||
|
INFOMANIAK_TTL="$DEFAULT_INFOMANIAK_TTL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#save the token to the account conf file.
|
||||||
|
_saveaccountconf_mutable INFOMANIAK_API_TOKEN "$INFOMANIAK_API_TOKEN"
|
||||||
|
|
||||||
|
if [ "$INFOMANIAK_API_URL" != "$DEFAULT_INFOMANIAK_API_URL" ]; then
|
||||||
|
_saveaccountconf_mutable INFOMANIAK_API_URL "$INFOMANIAK_API_URL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$INFOMANIAK_TTL" != "$DEFAULT_INFOMANIAK_TTL" ]; then
|
||||||
|
_saveaccountconf_mutable INFOMANIAK_TTL "$INFOMANIAK_TTL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
export _H1="Authorization: Bearer $INFOMANIAK_API_TOKEN"
|
||||||
|
export _H2="Content-Type: application/json"
|
||||||
|
|
||||||
|
fulldomain="$1"
|
||||||
|
txtvalue="$2"
|
||||||
|
|
||||||
|
_info "Infomaniak DNS API"
|
||||||
|
_debug fulldomain "$fulldomain"
|
||||||
|
_debug txtvalue "$txtvalue"
|
||||||
|
|
||||||
|
fqdn=${fulldomain#_acme-challenge.}
|
||||||
|
|
||||||
|
# guess which base domain to add record to
|
||||||
|
zone_and_id=$(_find_zone "$fqdn")
|
||||||
|
if [ -z "$zone_and_id" ]; then
|
||||||
|
_err "cannot find zone to modify"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
zone=${zone_and_id% *}
|
||||||
|
domain_id=${zone_and_id#* }
|
||||||
|
|
||||||
|
# extract first part of domain
|
||||||
|
key=${fulldomain%.$zone}
|
||||||
|
|
||||||
|
_debug "zone:$zone id:$domain_id key:$key"
|
||||||
|
|
||||||
|
# payload
|
||||||
|
data="{\"type\": \"TXT\", \"source\": \"$key\", \"target\": \"$txtvalue\", \"ttl\": $INFOMANIAK_TTL}"
|
||||||
|
|
||||||
|
# API call
|
||||||
|
response=$(_post "$data" "${INFOMANIAK_API_URL}/1/domain/$domain_id/dns/record")
|
||||||
|
if [ -n "$response" ] && echo "$response" | _contains '"result":"success"'; then
|
||||||
|
_info "Record added"
|
||||||
|
_debug "Response: $response"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
_err "could not create record"
|
||||||
|
_debug "Response: $response"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#Usage: fulldomain txtvalue
|
||||||
|
#Remove the txt record after validation.
|
||||||
|
dns_infomaniak_rm() {
|
||||||
|
|
||||||
|
INFOMANIAK_API_TOKEN="${INFOMANIAK_API_TOKEN:-$(_readaccountconf_mutable INFOMANIAK_API_TOKEN)}"
|
||||||
|
INFOMANIAK_API_URL="${INFOMANIAK_API_URL:-$(_readaccountconf_mutable INFOMANIAK_API_URL)}"
|
||||||
|
INFOMANIAK_TTL="${INFOMANIAK_TTL:-$(_readaccountconf_mutable INFOMANIAK_TTL)}"
|
||||||
|
|
||||||
|
if [ -z "$INFOMANIAK_API_TOKEN" ]; then
|
||||||
|
INFOMANIAK_API_TOKEN=""
|
||||||
|
_err "Please provide a valid Infomaniak API token in variable INFOMANIAK_API_TOKEN"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$INFOMANIAK_API_URL" ]; then
|
||||||
|
INFOMANIAK_API_URL="$DEFAULT_INFOMANIAK_API_URL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$INFOMANIAK_TTL" ]; then
|
||||||
|
INFOMANIAK_TTL="$DEFAULT_INFOMANIAK_TTL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#save the token to the account conf file.
|
||||||
|
_saveaccountconf_mutable INFOMANIAK_API_TOKEN "$INFOMANIAK_API_TOKEN"
|
||||||
|
|
||||||
|
if [ "$INFOMANIAK_API_URL" != "$DEFAULT_INFOMANIAK_API_URL" ]; then
|
||||||
|
_saveaccountconf_mutable INFOMANIAK_API_URL "$INFOMANIAK_API_URL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$INFOMANIAK_TTL" != "$DEFAULT_INFOMANIAK_TTL" ]; then
|
||||||
|
_saveaccountconf_mutable INFOMANIAK_TTL "$INFOMANIAK_TTL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
export _H1="Authorization: Bearer $INFOMANIAK_API_TOKEN"
|
||||||
|
export _H2="ContentType: application/json"
|
||||||
|
|
||||||
|
fulldomain=$1
|
||||||
|
txtvalue=$2
|
||||||
|
_info "Infomaniak DNS API"
|
||||||
|
_debug fulldomain "$fulldomain"
|
||||||
|
_debug txtvalue "$txtvalue"
|
||||||
|
|
||||||
|
fqdn=${fulldomain#_acme-challenge.}
|
||||||
|
|
||||||
|
# guess which base domain to add record to
|
||||||
|
zone_and_id=$(_find_zone "$fqdn")
|
||||||
|
if [ -z "$zone_and_id" ]; then
|
||||||
|
_err "cannot find zone to modify"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
zone=${zone_and_id% *}
|
||||||
|
domain_id=${zone_and_id#* }
|
||||||
|
|
||||||
|
# extract first part of domain
|
||||||
|
key=${fulldomain%.$zone}
|
||||||
|
|
||||||
|
_debug "zone:$zone id:$domain_id key:$key"
|
||||||
|
|
||||||
|
# find previous record
|
||||||
|
# shellcheck disable=SC1004
|
||||||
|
record_id=$(_get "${INFOMANIAK_API_URL}/1/domain/$domain_id/dns/record" | sed 's/.*"data":\[\(.*\)\]}/\1/; s/},{/}\
|
||||||
|
{/g' | sed -n 's/.*"id":"*\([0-9]*\)"*.*"source_idn":"'"$fulldomain"'".*"target_idn":"'"$txtvalue"'".*/\1/p')
|
||||||
|
if [ -z "$record_id" ]; then
|
||||||
|
_err "could not find record to delete"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug "record_id: $record_id"
|
||||||
|
|
||||||
|
# API call
|
||||||
|
response=$(_post "" "${INFOMANIAK_API_URL}/1/domain/$domain_id/dns/record/$record_id" "" DELETE)
|
||||||
|
if [ -n "$response" ] && echo "$response" | _contains '"result":"success"'; then
|
||||||
|
_info "Record deleted"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
_err "could not delete record"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#################### Private functions below ##################################
|
||||||
|
|
||||||
|
_get_domain_id() {
|
||||||
|
domain="$1"
|
||||||
|
|
||||||
|
# shellcheck disable=SC1004
|
||||||
|
_get "${INFOMANIAK_API_URL}/1/product?service_name=domain&customer_name=$domain" | sed 's/.*"data":\[{\(.*\)}\]}/\1/; s/,/\
|
||||||
|
/g' | sed -n 's/^"id":\(.*\)/\1/p'
|
||||||
|
}
|
||||||
|
|
||||||
|
_find_zone() {
|
||||||
|
zone="$1"
|
||||||
|
|
||||||
|
# find domain in list, removing . parts sequentialy
|
||||||
|
while _contains "$zone" '\.'; do
|
||||||
|
_debug "testing $zone"
|
||||||
|
id=$(_get_domain_id "$zone")
|
||||||
|
if [ -n "$id" ]; then
|
||||||
|
echo "$zone $id"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
zone=${zone#*.}
|
||||||
|
done
|
||||||
|
}
|
150
dnsapi/dns_kappernet.sh
Normal file
150
dnsapi/dns_kappernet.sh
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# kapper.net domain api
|
||||||
|
# for further questions please contact: support@kapper.net
|
||||||
|
# please report issues here: https://github.com/acmesh-official/acme.sh/issues/2977
|
||||||
|
|
||||||
|
#KAPPERNETDNS_Key="yourKAPPERNETapikey"
|
||||||
|
#KAPPERNETDNS_Secret="yourKAPPERNETapisecret"
|
||||||
|
|
||||||
|
KAPPERNETDNS_Api="https://dnspanel.kapper.net/API/1.2?APIKey=$KAPPERNETDNS_Key&APISecret=$KAPPERNETDNS_Secret"
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# called with
|
||||||
|
# fullhostname: something.example.com
|
||||||
|
# txtvalue: someacmegenerated string
|
||||||
|
dns_kappernet_add() {
|
||||||
|
fullhostname=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
KAPPERNETDNS_Key="${KAPPERNETDNS_Key:-$(_readaccountconf_mutable KAPPERNETDNS_Key)}"
|
||||||
|
KAPPERNETDNS_Secret="${KAPPERNETDNS_Secret:-$(_readaccountconf_mutable KAPPERNETDNS_Secret)}"
|
||||||
|
|
||||||
|
if [ -z "$KAPPERNETDNS_Key" ] || [ -z "$KAPPERNETDNS_Secret" ]; then
|
||||||
|
KAPPERNETDNS_Key=""
|
||||||
|
KAPPERNETDNS_Secret=""
|
||||||
|
_err "Please specify your kapper.net api key and secret."
|
||||||
|
_err "If you have not received yours - send your mail to"
|
||||||
|
_err "support@kapper.net to get your key and secret."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#store the api key and email to the account conf file.
|
||||||
|
_saveaccountconf_mutable KAPPERNETDNS_Key "$KAPPERNETDNS_Key"
|
||||||
|
_saveaccountconf_mutable KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret"
|
||||||
|
_debug "Checking Domain ..."
|
||||||
|
if ! _get_root "$fullhostname"; then
|
||||||
|
_err "invalid domain"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_debug _sub_domain "SUBDOMAIN: $_sub_domain"
|
||||||
|
_debug _domain "DOMAIN: $_domain"
|
||||||
|
|
||||||
|
_info "Trying to add TXT DNS Record"
|
||||||
|
data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%223600%22%2C%22prio%22%3A%22%22%7D"
|
||||||
|
if _kappernet_api GET "action=new&subject=$_domain&data=$data"; then
|
||||||
|
|
||||||
|
if _contains "$response" "{\"OK\":true"; then
|
||||||
|
_info "Waiting 120 seconds for DNS to spread the new record"
|
||||||
|
_sleep 120
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Error creating a TXT DNS Record: $fullhostname TXT $txtvalue"
|
||||||
|
_err "Error Message: $response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_err "Failed creating TXT Record"
|
||||||
|
}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# called with
|
||||||
|
# fullhostname: something.example.com
|
||||||
|
dns_kappernet_rm() {
|
||||||
|
fullhostname=$1
|
||||||
|
txtvalue=$2
|
||||||
|
|
||||||
|
KAPPERNETDNS_Key="${KAPPERNETDNS_Key:-$(_readaccountconf_mutable KAPPERNETDNS_Key)}"
|
||||||
|
KAPPERNETDNS_Secret="${KAPPERNETDNS_Secret:-$(_readaccountconf_mutable KAPPERNETDNS_Secret)}"
|
||||||
|
|
||||||
|
if [ -z "$KAPPERNETDNS_Key" ] || [ -z "$KAPPERNETDNS_Secret" ]; then
|
||||||
|
KAPPERNETDNS_Key=""
|
||||||
|
KAPPERNETDNS_Secret=""
|
||||||
|
_err "Please specify your kapper.net api key and secret."
|
||||||
|
_err "If you have not received yours - send your mail to"
|
||||||
|
_err "support@kapper.net to get your key and secret."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#store the api key and email to the account conf file.
|
||||||
|
_saveaccountconf_mutable KAPPERNETDNS_Key "$KAPPERNETDNS_Key"
|
||||||
|
_saveaccountconf_mutable KAPPERNETDNS_Secret "$KAPPERNETDNS_Secret"
|
||||||
|
|
||||||
|
_info "Trying to remove the TXT Record: $fullhostname containing $txtvalue"
|
||||||
|
data="%7B%22name%22%3A%22$fullhostname%22%2C%22type%22%3A%22TXT%22%2C%22content%22%3A%22$txtvalue%22%2C%22ttl%22%3A%223600%22%2C%22prio%22%3A%22%22%7D"
|
||||||
|
if _kappernet_api GET "action=del&subject=$fullhostname&data=$data"; then
|
||||||
|
if _contains "$response" "{\"OK\":true"; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Error deleting DNS Record: $fullhostname containing $txtvalue"
|
||||||
|
_err "Problem: $response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_err "Problem deleting TXT DNS record"
|
||||||
|
}
|
||||||
|
|
||||||
|
#################### Private functions below ##################################
|
||||||
|
# called with hostname
|
||||||
|
# e.g._acme-challenge.www.domain.com returns
|
||||||
|
# _sub_domain=_acme-challenge.www
|
||||||
|
# _domain=domain.com
|
||||||
|
_get_root() {
|
||||||
|
domain=$1
|
||||||
|
i=2
|
||||||
|
p=1
|
||||||
|
while true; do
|
||||||
|
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||||
|
if [ -z "$h" ]; then
|
||||||
|
#not valid
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if ! _kappernet_api GET "action=list&subject=$h"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if _contains "$response" '"OK":false'; then
|
||||||
|
_debug "$h not found"
|
||||||
|
else
|
||||||
|
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||||
|
_domain="$h"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
p="$i"
|
||||||
|
i=$(_math "$i" + 1)
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# calls the kapper.net DNS Panel API
|
||||||
|
# with
|
||||||
|
# method
|
||||||
|
# param
|
||||||
|
_kappernet_api() {
|
||||||
|
method=$1
|
||||||
|
param="$2"
|
||||||
|
|
||||||
|
_debug param "PARAMETER=$param"
|
||||||
|
url="$KAPPERNETDNS_Api&$param"
|
||||||
|
_debug url "URL=$url"
|
||||||
|
|
||||||
|
if [ "$method" = "GET" ]; then
|
||||||
|
response="$(_get "$url")"
|
||||||
|
else
|
||||||
|
_err "Unsupported method"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug2 response "$response"
|
||||||
|
return 0
|
||||||
|
}
|
@ -47,7 +47,7 @@ dns_misaka_add() {
|
|||||||
if [ "$count" = "0" ]; then
|
if [ "$count" = "0" ]; then
|
||||||
_info "Adding record"
|
_info "Adding record"
|
||||||
|
|
||||||
if _misaka_rest PUT "zones/${_domain}/recordsets/${_sub_domain}/TXT" "{\"records\":[{\"value\":\"\\\"$txtvalue\\\"\"}],\"filters\":[],\"ttl\":1}"; then
|
if _misaka_rest POST "zones/${_domain}/recordsets/${_sub_domain}/TXT" "{\"records\":[{\"value\":\"\\\"$txtvalue\\\"\"}],\"filters\":[],\"ttl\":1}"; then
|
||||||
_debug response "$response"
|
_debug response "$response"
|
||||||
if _contains "$response" "$_sub_domain"; then
|
if _contains "$response" "$_sub_domain"; then
|
||||||
_info "Added"
|
_info "Added"
|
||||||
@ -61,7 +61,7 @@ dns_misaka_add() {
|
|||||||
else
|
else
|
||||||
_info "Updating record"
|
_info "Updating record"
|
||||||
|
|
||||||
_misaka_rest POST "zones/${_domain}/recordsets/${_sub_domain}/TXT?append=true" "{\"records\": [{\"value\": \"\\\"$txtvalue\\\"\"}],\"ttl\":1}"
|
_misaka_rest PUT "zones/${_domain}/recordsets/${_sub_domain}/TXT?append=true" "{\"records\": [{\"value\": \"\\\"$txtvalue\\\"\"}],\"ttl\":1}"
|
||||||
if [ "$?" = "0" ] && _contains "$response" "$_sub_domain"; then
|
if [ "$?" = "0" ] && _contains "$response" "$_sub_domain"; then
|
||||||
_info "Updated!"
|
_info "Updated!"
|
||||||
#todo: check if the record takes effect
|
#todo: check if the record takes effect
|
||||||
|
162
dnsapi/dns_netlify.sh
Normal file
162
dnsapi/dns_netlify.sh
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
#!/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"
|
||||||
|
txtdomain="$1"
|
||||||
|
txt="$2"
|
||||||
|
_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
|
||||||
|
}
|
@ -166,7 +166,7 @@ _get_root() {
|
|||||||
if _contains "$_all_domains" "^$h$"; then
|
if _contains "$_all_domains" "^$h$"; then
|
||||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||||
_domain=$h
|
_domain=$h
|
||||||
_service=$(printf "%s" "$response" | grep "idn-name=\"$_domain\"" | sed -r "s/.*service=\"(.*)\".*$/\1/")
|
_service=$(printf "%s" "$response" | grep -m 1 "idn-name=\"$_domain\"" | sed -r "s/.*service=\"(.*)\".*$/\1/")
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
p="$i"
|
p="$i"
|
||||||
|
348
dnsapi/dns_openstack.sh
Executable file
348
dnsapi/dns_openstack.sh
Executable 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
|
||||||
|
}
|
@ -248,7 +248,7 @@ _ovh_authentication() {
|
|||||||
# _domain=domain.com
|
# _domain=domain.com
|
||||||
_get_root() {
|
_get_root() {
|
||||||
domain=$1
|
domain=$1
|
||||||
i=2
|
i=1
|
||||||
p=1
|
p=1
|
||||||
while true; do
|
while true; do
|
||||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||||
|
@ -136,11 +136,12 @@ dns_pleskxml_rm() {
|
|||||||
|
|
||||||
# Reduce output to one line per DNS record, filtered for TXT records with a record ID only (which they should all have)
|
# Reduce output to one line per DNS record, filtered for TXT records with a record ID only (which they should all have)
|
||||||
# Also strip out spaces between tags, redundant <data> and </data> group tags and any <self-closing/> tags
|
# Also strip out spaces between tags, redundant <data> and </data> group tags and any <self-closing/> tags
|
||||||
reclist="$(_api_response_split "$pleskxml_prettyprint_result" 'result' '<status>ok</status>' \
|
reclist="$(
|
||||||
| sed 's# \{1,\}<\([a-zA-Z]\)#<\1#g;s#</\{0,1\}data>##g;s#<[a-z][^/<>]*/>##g' \
|
_api_response_split "$pleskxml_prettyprint_result" 'result' '<status>ok</status>' |
|
||||||
| grep "<site-id>${root_domain_id}</site-id>" \
|
sed 's# \{1,\}<\([a-zA-Z]\)#<\1#g;s#</\{0,1\}data>##g;s#<[a-z][^/<>]*/>##g' |
|
||||||
| grep '<id>[0-9]\{1,\}</id>' \
|
grep "<site-id>${root_domain_id}</site-id>" |
|
||||||
| grep '<type>TXT</type>'
|
grep '<id>[0-9]\{1,\}</id>' |
|
||||||
|
grep '<type>TXT</type>'
|
||||||
)"
|
)"
|
||||||
|
|
||||||
if [ -z "$reclist" ]; then
|
if [ -z "$reclist" ]; then
|
||||||
@ -151,10 +152,11 @@ dns_pleskxml_rm() {
|
|||||||
_debug "Got list of DNS TXT records for root domain '$root_domain_name':"
|
_debug "Got list of DNS TXT records for root domain '$root_domain_name':"
|
||||||
_debug "$reclist"
|
_debug "$reclist"
|
||||||
|
|
||||||
recid="$(_value "$reclist" \
|
recid="$(
|
||||||
| grep "<host>${fulldomain}.</host>" \
|
_value "$reclist" |
|
||||||
| grep "<value>${txtvalue}</value>" \
|
grep "<host>${fulldomain}.</host>" |
|
||||||
| sed 's/^.*<id>\([0-9]\{1,\}\)<\/id>.*$/\1/'
|
grep "<value>${txtvalue}</value>" |
|
||||||
|
sed 's/^.*<id>\([0-9]\{1,\}\)<\/id>.*$/\1/'
|
||||||
)"
|
)"
|
||||||
|
|
||||||
if ! _value "$recid" | grep '^[0-9]\{1,\}$' >/dev/null; then
|
if ! _value "$recid" | grep '^[0-9]\{1,\}$' >/dev/null; then
|
||||||
@ -220,11 +222,11 @@ _countdots() {
|
|||||||
# Last line could change to <sed -n '/.../p'> instead, with suitable escaping of ['"/$],
|
# Last line could change to <sed -n '/.../p'> instead, with suitable escaping of ['"/$],
|
||||||
# if future Plesk XML API changes ever require extended regex
|
# if future Plesk XML API changes ever require extended regex
|
||||||
_api_response_split() {
|
_api_response_split() {
|
||||||
printf '%s' "$1" \
|
printf '%s' "$1" |
|
||||||
| sed 's/^ +//;s/ +$//' \
|
sed 's/^ +//;s/ +$//' |
|
||||||
| tr -d '\n\r' \
|
tr -d '\n\r' |
|
||||||
| sed "s/<\/\{0,1\}$2>/${NEWLINE}/g" \
|
sed "s/<\/\{0,1\}$2>/${NEWLINE}/g" |
|
||||||
| grep "$3"
|
grep "$3"
|
||||||
}
|
}
|
||||||
|
|
||||||
#################### Private functions below (DNS functions) ##################################
|
#################### Private functions below (DNS functions) ##################################
|
||||||
@ -265,10 +267,11 @@ _call_api() {
|
|||||||
# - filter output to keep only lines like this: "SPACES<TAG>text</TAG>SPACES" (shouldn't be necessary with prettyprint but guarantees subsequent code is ok)
|
# - filter output to keep only lines like this: "SPACES<TAG>text</TAG>SPACES" (shouldn't be necessary with prettyprint but guarantees subsequent code is ok)
|
||||||
# - then edit the 3 "useful" error tokens individually and remove closing tags on all lines
|
# - then edit the 3 "useful" error tokens individually and remove closing tags on all lines
|
||||||
# - then filter again to remove all lines not edited (which will be the lines not starting A-Z)
|
# - then filter again to remove all lines not edited (which will be the lines not starting A-Z)
|
||||||
errtext="$(_value "$pleskxml_prettyprint_result" \
|
errtext="$(
|
||||||
| grep '^ *<[a-z]\{1,\}>[^<]*<\/[a-z]\{1,\}> *$' \
|
_value "$pleskxml_prettyprint_result" |
|
||||||
| sed 's/^ *<status>/Status: /;s/^ *<errcode>/Error code: /;s/^ *<errtext>/Error text: /;s/<\/.*$//' \
|
grep '^ *<[a-z]\{1,\}>[^<]*<\/[a-z]\{1,\}> *$' |
|
||||||
| grep '^[A-Z]'
|
sed 's/^ *<status>/Status: /;s/^ *<errcode>/Error code: /;s/^ *<errtext>/Error text: /;s/<\/.*$//' |
|
||||||
|
grep '^[A-Z]'
|
||||||
)"
|
)"
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
@ -33,8 +33,11 @@ dns_regru_add() {
|
|||||||
fi
|
fi
|
||||||
_debug _domain "$_domain"
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
|
_subdomain=$(echo "$fulldomain" | sed -r "s/.$_domain//")
|
||||||
|
_debug _subdomain "$_subdomain"
|
||||||
|
|
||||||
_info "Adding TXT record to ${fulldomain}"
|
_info "Adding TXT record to ${fulldomain}"
|
||||||
_regru_rest POST "zone/add_txt" "input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22_acme-challenge%22,%22text%22:%22${txtvalue}%22,%22output_content_type%22:%22plain%22}&input_format=json"
|
_regru_rest POST "zone/add_txt" "input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22${_subdomain}%22,%22text%22:%22${txtvalue}%22,%22output_content_type%22:%22plain%22}&input_format=json"
|
||||||
|
|
||||||
if ! _contains "${response}" 'error'; then
|
if ! _contains "${response}" 'error'; then
|
||||||
return 0
|
return 0
|
||||||
@ -64,8 +67,11 @@ dns_regru_rm() {
|
|||||||
fi
|
fi
|
||||||
_debug _domain "$_domain"
|
_debug _domain "$_domain"
|
||||||
|
|
||||||
|
_subdomain=$(echo "$fulldomain" | sed -r "s/.$_domain//")
|
||||||
|
_debug _subdomain "$_subdomain"
|
||||||
|
|
||||||
_info "Deleting resource record $fulldomain"
|
_info "Deleting resource record $fulldomain"
|
||||||
_regru_rest POST "zone/remove_record" "input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22_acme-challenge%22,%22content%22:%22${txtvalue}%22,%22record_type%22:%22TXT%22,%22output_content_type%22:%22plain%22}&input_format=json"
|
_regru_rest POST "zone/remove_record" "input_data={%22username%22:%22${REGRU_API_Username}%22,%22password%22:%22${REGRU_API_Password}%22,%22domains%22:[{%22dname%22:%22${_domain}%22}],%22subdomain%22:%22${_subdomain}%22,%22content%22:%22${txtvalue}%22,%22record_type%22:%22TXT%22,%22output_content_type%22:%22plain%22}&input_format=json"
|
||||||
|
|
||||||
if ! _contains "${response}" 'error'; then
|
if ! _contains "${response}" 'error'; then
|
||||||
return 0
|
return 0
|
||||||
|
@ -25,7 +25,7 @@ dns_yandex_add() {
|
|||||||
_PDD_get_record_ids || return 1
|
_PDD_get_record_ids || return 1
|
||||||
_debug "Record_ids: $record_ids"
|
_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."
|
_info "All existing $subdomain records from $domain will be removed at the very end."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user