From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id D23501FF187 for ; Mon, 3 Nov 2025 09:03:16 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id F2C8D13E44; Mon, 3 Nov 2025 09:03:45 +0100 (CET) From: Nicolas Frey To: pve-devel@lists.proxmox.com Date: Mon, 3 Nov 2025 09:03:09 +0100 Message-ID: <20251103080310.60168-2-n.frey@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251103080310.60168-1-n.frey@proxmox.com> References: <20251103080310.60168-1-n.frey@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.099 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods KAM_SHORT 0.001 Use of a URL Shortener for very short URL RDNS_NONE 0.793 Delivered to internal network by a host with no rDNS SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record Subject: [pve-devel] [PATCH proxmox-acme 1/2] dns: schema: add generate schema script X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox VE development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" Create a bash script, which parses out the required information using the `dns__info` variable in each of the providers' dnsapi scripts. This variable includes the Options, their descriptions and sometimes the default/optional values.This is then used to generate the json schema, which is then normalized. If the contents of the variable are malformed or it is empty, an empty entry will be generated. Signed-off-by: Nicolas Frey --- src/Makefile | 4 ++ src/generate_schema.sh | 135 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100755 src/generate_schema.sh diff --git a/src/Makefile b/src/Makefile index 9ee97c9..2a0d567 100644 --- a/src/Makefile +++ b/src/Makefile @@ -176,6 +176,10 @@ normalize-schema: dns-challenge-schema.json $^ > $^.tmp mv $^.tmp $^ +.PHONY: generate-schema +generate-schema: + ./generate_schema.sh -o dns-challenge-schema.json + .PHONY: install install: install -D -m 0744 proxmox-acme ${DESTDIR}${ACMEDIR}/proxmox-acme diff --git a/src/generate_schema.sh b/src/generate_schema.sh new file mode 100755 index 0000000..993ca6e --- /dev/null +++ b/src/generate_schema.sh @@ -0,0 +1,135 @@ +#!/usr/bin/bash + +# This script generates a valid dns challenge schema using information provided by the +# semi-structured dns_*_info in all dnsapi scripts provided by acme.sh. +# +# If the variable is not structured the way it is expected or present, then it will simply +# generate an empty entry in the schema (as of writing this, this is only the case for mydevil +# and selectel) this could then manually be corrected if necessary. + +set -euo pipefail + +output="" + +while getopts ":o:" opt; do + case $opt in + o) + output="$OPTARG" + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + exit 1 + ;; + :) + echo "Option -$OPTARG requires an argument" >&2 + exit 1 + ;; + esac +done +shift $((OPTIND - 1)) + +DNSAPI_DIR="${1:-./acme.sh/dnsapi}" +first=true +declare -a not_generated=() + +json_escape() { + printf '%s' "$1" \ + | sed -E \ + -e 's/\\/\\\\/g' \ + -e 's/"/\\"/g' \ + -e 's/\r/\\r/g' \ + -e 's/\n/\\n/g' \ + -e 's/\t/\\t/g' +} + +gen_schema() { + echo "{" + + for f in "$DNSAPI_DIR"/dns_*.sh; do + [[ -f "$f" ]] || continue + + # Extract dns_xxx_info=' ... ' + info=$(awk ' + BEGIN {in_info=0; text=""} + /^dns_.*_info='\''/ { + in_info=1 + sub(/^dns_.*_info='\''/, "") + text=$0 + next + } + in_info { + if ($0 ~ /'\''$/) { + sub(/'\''$/, "") + text=text"\n"$0 + in_info=0 + print text + } else { + text=text"\n"$0 + } + }' "$f") + + provider=$(basename "$f" .sh | sed 's/^dns_//') + + name=$(echo "$info" | head -n 1) + # if site information is wanted/needed? + # site=$(echo "$info" | grep -E "^Site:" | sed 's/^Site:[[:space:]]*//' || true) + + declare -A fields=() + while read -r var desc; do + [[ -z "$var" || -z "$desc" ]] && continue + fields["$var"]="$desc" + done < <(echo "$info" | awk '/^Options:/ {opt=1; next} opt && NF {if ($1=="Issues:"||$1=="Author:") exit; print}') + + # info was not found or malformed, add to list + if [ ${#fields[@]} -eq 0 ]; then + not_generated+=("$provider") + fi + + $first || echo "," + first=false + + echo "\"$(json_escape "$provider")\": {" + echo "\"fields\": {" + first_field=true + for k in "${!fields[@]}"; do + $first_field || echo "," + first_field=false + desc=${fields[$k]} + echo "\"$(json_escape "$k")\": {" + echo "\"description\":\"$(json_escape "$desc")\"," + echo "\"type\":\"string\"" + # parse out if a value is optional through the description + echo $desc | grep -qi "optional" && echo ",\"optional\": \"1\"" + # * after 'Default:', rm full stop rm quotation marks + # parse out if a value has a default through the description | | | + echo $desc | grep -q "Default:" && echo ",\"default\": \"$(echo "$desc" | sed -n 's/.*\bDefault: *//p' | sed 's/.$//' | tr -d '"')\"" + echo "}" + done + echo "}," + echo "\"name\": \"$(json_escape "$name")\"" + # echo "\"site\":\"$(json_escape "$site")\"" + echo "}" + done + + echo "}" +} + +if [ -n "$output" ]; then + gen_schema > "$output" + # normalize schema + perl -MJSON -0777 \ + -E 'print JSON->new->utf8->pretty->canonical->space_before(0)->encode(decode_json(<>))' \ + "$output" > "$output.tmp" + mv "$output.tmp" "$output" +else + # if -o is omitted, it will simply print to stdout + gen_schema +fi + +if [ ${#not_generated[@]} -gt 0 ]; then + echo "Some entries could not be (fully) generated:" +fi + +for i in "${not_generated[@]}"; do + echo " - $i" +done -- 2.47.3 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel