diff options
author | Daniel Peukert | 2020-07-09 15:50:20 +0200 |
---|---|---|
committer | Daniel Peukert | 2020-07-09 15:50:20 +0200 |
commit | 4beaf587542a891adcf35171260ecf3dbcbc36ca (patch) | |
tree | 5e8b8982e828e8377cca271fd3af097b72f9b8f5 | |
parent | 7fb32a4dfae347283e355fb0e82f77545c82ba9c (diff) | |
download | aur-4beaf587542a891adcf35171260ecf3dbcbc36ca.tar.gz |
Added certbot-dns-vultr files as upstream has disappeared
-rw-r--r-- | .SRCINFO | 10 | ||||
-rw-r--r-- | LICENSE | 21 | ||||
-rw-r--r-- | PKGBUILD | 14 | ||||
-rw-r--r-- | vultr-hook.py | 103 |
4 files changed, 139 insertions, 9 deletions
@@ -1,8 +1,8 @@ pkgbase = certbot-dns-vultr pkgdesc = Cerbot hooks for Vultr DNS pkgver = 20190506 - pkgrel = 4 - url = https://github.com/oefd/certbot-dns-vultr + pkgrel = 5 + url = https://aur.archlinux.org/packages/certbot-dns-vultr install = certbot-dns-vultr.install arch = any license = MIT @@ -13,7 +13,9 @@ pkgbase = certbot-dns-vultr depends = python-idna depends = python-requests depends = python-urllib3 - source = certbot-dns-vultr-20190506-4.tar.gz::https://github.com/oefd/certbot-dns-vultr/archive/5acb7e2b6d66f21decb3a37ed0d7ec808eefe844.tar.gz - sha256sums = afd6998a24c52d87f95610de1da8038e9b6701b0532ba0e40d50d17e8d2ddcfb + source = vultr-hook.py + source = LICENSE + sha256sums = 43c495691b0eb56d11f1d63beb6ecd5d24c8b7c4919af1282db1d3269c551e0f + sha256sums = 64d6e8ad6b22d73c7df31f140996f0f0356d1837199f048d3d544c032ad9823e pkgname = certbot-dns-vultr diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000000..410f1b5c0e53 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Terry Kerr + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. @@ -2,18 +2,22 @@ pkgname='certbot-dns-vultr' pkgver='20190506' _commit='5acb7e2b6d66f21decb3a37ed0d7ec808eefe844' -pkgrel='4' +pkgrel='5' pkgdesc='Cerbot hooks for Vultr DNS' arch=('any') -url="https://github.com/oefd/$pkgname" +url="https://aur.archlinux.org/packages/$pkgname" license=('MIT') depends=('certbot' 'python' 'python-certifi' 'python-chardet' 'python-idna' 'python-requests' 'python-urllib3') install="$pkgname.install" -source=("$pkgname-$pkgver-$pkgrel.tar.gz::$url/archive/$_commit.tar.gz") -sha256sums=('afd6998a24c52d87f95610de1da8038e9b6701b0532ba0e40d50d17e8d2ddcfb') +source=( + 'vultr-hook.py' + 'LICENSE' +) +sha256sums=('43c495691b0eb56d11f1d63beb6ecd5d24c8b7c4919af1282db1d3269c551e0f' + '64d6e8ad6b22d73c7df31f140996f0f0356d1837199f048d3d544c032ad9823e') package() { - cd "$srcdir/$pkgname-$_commit/" + cd "$srcdir/" install -Dm755 'vultr-hook.py' "$pkgdir/usr/bin/$pkgname" install -Dm644 'LICENSE' "$pkgdir/usr/share/licenses/$pkgname/LICENSE" } diff --git a/vultr-hook.py b/vultr-hook.py new file mode 100644 index 000000000000..41a110905668 --- /dev/null +++ b/vultr-hook.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +import os +import requests +import sys +from typing import Iterator + +DOMAIN = os.environ.get("CERTBOT_DOMAIN") +TOKEN = os.environ.get("CERTBOT_VALIDATION") +AUTH_OUTPUT = os.environ.get("CERTBOT_AUTH_OUTPUT") +API_KEY = os.environ.get("VULTR_API_KEY") + +API_EP = "https://api.vultr.com/v1/" +DOMAIN_LIST_EP = "{}{}".format(API_EP, "dns/list") +RECORD_LIST_EP = "{}{}".format(API_EP, "dns/records") +RECORD_ADD_EP = "{}{}".format(API_EP, "dns/create_record") +RECORD_DEL_EP = "{}{}".format(API_EP, "dns/delete_record") +SESSION = requests.Session() +SESSION.headers.update({"API-Key": API_KEY}) + + +def main(): + if None in [DOMAIN, TOKEN, API_KEY]: + sys.stderr.write("CERTBOT_DOMAIN, CERTBOT_VALIDATION " + " and VULTR_API_KEY must all be defined\n") + sys.exit(1) + + if AUTH_OUTPUT is None: + pre_hook() + else: + post_hook() + + +def subdomains(domain: str) -> Iterator[str]: + """Generator of all subdomains within the domain, + given from the longest to the shortest. + + Ex: "one.two.three" -> + "one.two.three" + "two.three" + "three" + """ + for i in range(domain.count(".") + 1): + yield domain.split(".", i)[-1] + + +def pre_hook(): + """Add a new TXT record.""" + + # extract all domains managed by the Vultr API + managed_domains = SESSION.get(DOMAIN_LIST_EP).json() + managed_domains = [o["domain"] for o in managed_domains] + managed_domain = None + + # find the subdomain of DOMAIN managed by Vultr + for subdomain in subdomains(DOMAIN): + if subdomain in managed_domains: + managed_domain = subdomain + break + if managed_domain is None: + raise ValueError( + "no suitable managed domain found for {}".format(DOMAIN)) + + # echo managed domain for post hook to pick up + sys.stdout.write(managed_domain) + + # get the subdomain part relative to the managed domain + subdomain = DOMAIN.rpartition(managed_domain)[0][:-1] + + # add the record + if subdomain == "": + name = "_acme-challenge" + else: + name = "_acme-challenge.{}".format(subdomain) + SESSION.post( + RECORD_ADD_EP, + data={ + "domain": managed_domain, + "name": name, + "type": "TXT", + "data": '"{}"'.format(TOKEN), + }).raise_for_status() + + +def post_hook(): + """Remove the added TXT record.""" + + managed_domain = AUTH_OUTPUT + records = SESSION.get( + RECORD_LIST_EP, params={ + "domain": managed_domain, + }).json() + txt_records = [r for r in records if r["type"] == "TXT"] + record = [r for r in txt_records if r["data"] == '"{}"'.format(TOKEN)][0] + SESSION.post( + RECORD_DEL_EP, + data={ + "domain": managed_domain, + "RECORDID": record["RECORDID"] + }).raise_for_status() + + +if __name__ == "__main__": + main() |