From 6decdb445d7733eaa72ee26c78c53bf54f25897d Mon Sep 17 00:00:00 2001 From: Jack Jackson Date: Mon, 22 Aug 2022 13:20:02 -0700 Subject: [PATCH] Enable options for certificate and domain --- dns_update.sh | 84 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 23 deletions(-) diff --git a/dns_update.sh b/dns_update.sh index c739aa6..998c285 100755 --- a/dns_update.sh +++ b/dns_update.sh @@ -1,30 +1,68 @@ -#!/bin/sh +#!/bin/bash set -eux -# First argument is cloudflared config file -# TODO - make this optional, and check standard locations if absent. -# Not doing it now because that would require me to remember how to -# do named arguments with bash (I think it's `getopt`?), and ain't -# nobody got time for that. -if [ $# -lt 1 ]; then - echo "Requires an argument pointing to the config file"; - exit 1; -fi -CONFIG_FILE_LOCATION=$1 -if [ ! -f $CONFIG_FILE_LOCATION ]; then - echo "File \"$CONFIG_FILE_LOCATION\" does not exist"; +# https://stackoverflow.com/a/14203146/1040915 +POSITIONAL_ARGS=() + +while [[ $# -gt 0 ]]; do + case $1 in + --config) + # Provide a path to the Cloudflared Config file. + # Required, since we need to parse the config file to find tunnel name. + # (If I was less lazy, I would implement cloudflared-like behaviour to search + # the standard locations if absent. But I am, so I didn't :P ) + CONFIG="$2" + shift # past argument + shift # past value + ;; + --cert) + # Provide a path to the Cloudflared certificate. + # If absent, Cloudflared will search the standard locations (as above). + # ([`/etc/cloudflared/`, `/usr/local/etc/cloudflared`, `$HOME/.cloudflared`]) + CERT="$2" + shift # past argument + shift # past value + ;; + -d|--domain) + # If set, only try to update DNS for names that are subdomains of this domain. + # If not set, try to update all names. + DOMAIN="$2" + shift # past argument + shift # past value + ;; + -*|--*) + echo "Unknown option $1" + exit 1 + ;; + *) + POSITIONAL_ARGS+=("$1") # save positional arg + shift # past argument + ;; + esac +done + +if [[ -z $CONFIG ]]; then + echo "Path to config file must be provided"; exit 1; fi -# Second argument is "root domain". -# If set, only try to update DNS for names that are subdomains of this domain. -# If not set, try to update all names -TUNNEL_NAME=$(yq ".tunnel" $CONFIG_FILE_LOCATION); -if [ $# -gt 1 ]; then - ROOT_DOMAIN=$2; - yq ".ingress[].hostname | select(. != null) | select (. == \"*$ROOT_DOMAIN\")" $CONFIG_FILE_LOCATION | xargs -I {} cloudflared tunnel route dns $TUNNEL_NAME {}; -else - yq '.ingress[].hostname | select(. != null)' $CONFIG_FILE_LOCATION | xargs -I {} cloudflared tunnel route dns $TUNNEL_NAME {}; -fi +set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters +TUNNEL_NAME=$(yq ".tunnel" $CONFIG); + +COMMAND_STRING="yq \".ingress[].hostname | select(. != null)"; +if [[ -n "$DOMAIN" ]]; then + COMMAND_STRING="$COMMAND_STRING | select (. == \\\"*$DOMAIN\\\")"; +fi +# Note closing double-quote, from start of COMMAND_STRING +COMMAND_STRING="$COMMAND_STRING\" $CONFIG | xargs -I {} cloudflared tunnel"; +if [[ -n "$CERT" ]]; then + COMMAND_STRING="$COMMAND_STRING --origincert $CERT"; +fi +COMMAND_STRING="$COMMAND_STRING route dns $TUNNEL_NAME {}"; + + +# I don't know enough about bash security to know whether there's a risk of injection here: +# be careful where you accept script parameters from! +eval $COMMAND_STRING