From 4eafd3b5b772379e38c1d3b3db0730673c7cd173 Mon Sep 17 00:00:00 2001 From: dragonhunt02 Date: Sat, 22 Mar 2025 22:01:00 +0000 Subject: [PATCH] feat: implement proxy container :label functionality --- plugins/caddy-vhosts/command-functions | 11 +++ .../caddy-vhosts/docker-args-process-deploy | 10 +++ plugins/caddy-vhosts/help-functions | 1 + plugins/caddy-vhosts/subcommands/label | 6 ++ plugins/haproxy-vhosts/command-functions | 11 +++ .../haproxy-vhosts/docker-args-process-deploy | 10 +++ plugins/haproxy-vhosts/help-functions | 1 + plugins/haproxy-vhosts/subcommands/label | 6 ++ plugins/openresty-vhosts/command-functions | 11 +++ .../docker-args-process-deploy | 10 +++ plugins/openresty-vhosts/help-functions | 1 + plugins/openresty-vhosts/subcommands/label | 6 ++ plugins/proxy/command-functions | 84 +++++++++++++++++++ plugins/proxy/functions | 77 +++++++++++++++++ plugins/traefik-vhosts/command-functions | 11 +++ .../traefik-vhosts/docker-args-process-deploy | 10 +++ plugins/traefik-vhosts/help-functions | 1 + plugins/traefik-vhosts/subcommands/label | 6 ++ 18 files changed, 273 insertions(+) create mode 100755 plugins/caddy-vhosts/subcommands/label create mode 100755 plugins/haproxy-vhosts/subcommands/label create mode 100755 plugins/openresty-vhosts/subcommands/label create mode 100755 plugins/proxy/command-functions create mode 100755 plugins/proxy/functions create mode 100755 plugins/traefik-vhosts/subcommands/label diff --git a/plugins/caddy-vhosts/command-functions b/plugins/caddy-vhosts/command-functions index 1f04357ff..e515e2820 100755 --- a/plugins/caddy-vhosts/command-functions +++ b/plugins/caddy-vhosts/command-functions @@ -1,9 +1,20 @@ #!/usr/bin/env bash source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_AVAILABLE_PATH/proxy/command-functions" source "$PLUGIN_AVAILABLE_PATH/caddy-vhosts/internal-functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x +cmd-caddy-label() { + declare desc="set/unset/show container proxy labels" + declare cmd="caddy:label" + [[ "$1" == "$cmd" ]] && shift 1 + declare APP="$1" + + set -- caddy "$@" + cmd-proxy-label "$@" +} + cmd-caddy-report() { declare desc="displays a caddy report for one or more apps" declare cmd="caddy:report" diff --git a/plugins/caddy-vhosts/docker-args-process-deploy b/plugins/caddy-vhosts/docker-args-process-deploy index 9dd1f61f1..1be3b7f3a 100755 --- a/plugins/caddy-vhosts/docker-args-process-deploy +++ b/plugins/caddy-vhosts/docker-args-process-deploy @@ -1,5 +1,6 @@ #!/usr/bin/env bash source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_AVAILABLE_PATH/proxy/functions" source "$PLUGIN_AVAILABLE_PATH/caddy-vhosts/internal-functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x @@ -129,6 +130,15 @@ trigger-caddy-vhosts-docker-args-process-deploy() { fi fi + local proxy_labels_file_path=$(fn-proxy-get-labels-file-path "$APP" caddy) + fn-proxy-report-label-overwrite "$output" "$proxy_labels_file_path" + + if [[ -f "$proxy_labels_file_path" ]]; then + local user_proxy_labels="$(<"$proxy_labels_file_path")" + user_proxy_labels="$(echo "$user_proxy_labels" | tr '\r\n' ' ')" + output="$output $user_proxy_labels" + fi + echo -n "$STDIN$output" } diff --git a/plugins/caddy-vhosts/help-functions b/plugins/caddy-vhosts/help-functions index 287ffed04..76b161ef3 100755 --- a/plugins/caddy-vhosts/help-functions +++ b/plugins/caddy-vhosts/help-functions @@ -30,6 +30,7 @@ fn-help-content() { caddy:report [] [], Displays an caddy report for one or more apps caddy:set (), Set or clear an caddy property for an app caddy:show-config , Display caddy compose config + caddy:label (), Show, set or clear a caddy label for an app caddy:start, Starts the caddy server caddy:stop, Stops the caddy server help_content diff --git a/plugins/caddy-vhosts/subcommands/label b/plugins/caddy-vhosts/subcommands/label new file mode 100755 index 000000000..2a5e0421b --- /dev/null +++ b/plugins/caddy-vhosts/subcommands/label @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +source "$PLUGIN_AVAILABLE_PATH/caddy-vhosts/command-functions" +set -eo pipefail +[[ $DOKKU_TRACE ]] && set -x + +cmd-caddy-label "$@" diff --git a/plugins/haproxy-vhosts/command-functions b/plugins/haproxy-vhosts/command-functions index 481a6a682..f7ce1be91 100755 --- a/plugins/haproxy-vhosts/command-functions +++ b/plugins/haproxy-vhosts/command-functions @@ -1,9 +1,20 @@ #!/usr/bin/env bash source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_AVAILABLE_PATH/proxy/command-functions" source "$PLUGIN_AVAILABLE_PATH/haproxy-vhosts/internal-functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x +cmd-haproxy-label() { + declare desc="set/unset/show container proxy labels" + declare cmd="haproxy:label" + [[ "$1" == "$cmd" ]] && shift 1 + declare APP="$1" + + set -- haproxy "$@" + cmd-proxy-label "$@" +} + cmd-haproxy-report() { declare desc="displays a haproxy report for one or more apps" declare cmd="haproxy:report" diff --git a/plugins/haproxy-vhosts/docker-args-process-deploy b/plugins/haproxy-vhosts/docker-args-process-deploy index 60577f9cf..e60931fc7 100755 --- a/plugins/haproxy-vhosts/docker-args-process-deploy +++ b/plugins/haproxy-vhosts/docker-args-process-deploy @@ -1,5 +1,6 @@ #!/usr/bin/env bash source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_AVAILABLE_PATH/proxy/functions" source "$PLUGIN_AVAILABLE_PATH/haproxy-vhosts/internal-functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x @@ -123,6 +124,15 @@ trigger-haproxy-vhosts-docker-args-process-deploy() { fi fi + local proxy_labels_file_path=$(fn-proxy-get-labels-file-path "$APP" haproxy) + fn-proxy-report-label-overwrite "$output" "$proxy_labels_file_path" + + if [[ -f "$proxy_labels_file_path" ]]; then + local user_proxy_labels="$(<"$proxy_labels_file_path")" + user_proxy_labels="$(echo "$user_proxy_labels" | tr '\r\n' ' ')" + output="$output $user_proxy_labels" + fi + echo -n "$STDIN$output" } diff --git a/plugins/haproxy-vhosts/help-functions b/plugins/haproxy-vhosts/help-functions index b28fd2b1f..1c7f86674 100755 --- a/plugins/haproxy-vhosts/help-functions +++ b/plugins/haproxy-vhosts/help-functions @@ -30,6 +30,7 @@ fn-help-content() { haproxy:report [] [], Displays an haproxy report for one or more apps haproxy:set (), Set or clear an haproxy property for an app haproxy:show-config , Display haproxy compose config + haproxy:label (), Show, set or clear a haproxy label for an app haproxy:start, Starts the haproxy server haproxy:stop, Stops the haproxy server help_content diff --git a/plugins/haproxy-vhosts/subcommands/label b/plugins/haproxy-vhosts/subcommands/label new file mode 100755 index 000000000..d52aa7b16 --- /dev/null +++ b/plugins/haproxy-vhosts/subcommands/label @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +source "$PLUGIN_AVAILABLE_PATH/haproxy-vhosts/command-functions" +set -eo pipefail +[[ $DOKKU_TRACE ]] && set -x + +cmd-haproxy-label "$@" diff --git a/plugins/openresty-vhosts/command-functions b/plugins/openresty-vhosts/command-functions index 926839ff4..d9f6401c7 100755 --- a/plugins/openresty-vhosts/command-functions +++ b/plugins/openresty-vhosts/command-functions @@ -1,9 +1,20 @@ #!/usr/bin/env bash source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_AVAILABLE_PATH/proxy/command-functions" source "$PLUGIN_AVAILABLE_PATH/openresty-vhosts/internal-functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x +cmd-openresty-label() { + declare desc="set/unset/show container proxy labels" + declare cmd="openresty:label" + [[ "$1" == "$cmd" ]] && shift 1 + declare APP="$1" + + set -- openresty "$@" + cmd-proxy-label "$@" +} + cmd-openresty-report() { declare desc="displays a openresty report for one or more apps" declare cmd="openresty:report" diff --git a/plugins/openresty-vhosts/docker-args-process-deploy b/plugins/openresty-vhosts/docker-args-process-deploy index beefa73e3..6c116b2e2 100755 --- a/plugins/openresty-vhosts/docker-args-process-deploy +++ b/plugins/openresty-vhosts/docker-args-process-deploy @@ -2,6 +2,7 @@ set -eo pipefail [[ $DOKKU_TRACE ]] && set -x source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_AVAILABLE_PATH/proxy/functions" source "$PLUGIN_AVAILABLE_PATH/openresty-vhosts/internal-functions" trigger-openresty-vhosts-docker-args-process-deploy() { @@ -181,6 +182,15 @@ trigger-openresty-vhosts-docker-args-process-deploy() { value="$(fn-openresty-x-forwarded-ssl "$APP")" [[ -n "$value" ]] && output="$output '--label=openresty.x-forwarded-ssl=$value'" + local proxy_labels_file_path=$(fn-proxy-get-labels-file-path "$APP" openresty) + fn-proxy-report-label-overwrite "$output" "$proxy_labels_file_path" + + if [[ -f "$proxy_labels_file_path" ]]; then + local user_proxy_labels="$(<"$proxy_labels_file_path")" + user_proxy_labels="$(echo "$user_proxy_labels" | tr '\r\n' ' ')" + output="$output $user_proxy_labels" + fi + echo -n "$STDIN$output" } diff --git a/plugins/openresty-vhosts/help-functions b/plugins/openresty-vhosts/help-functions index d8fc19e7a..d8a8414fc 100755 --- a/plugins/openresty-vhosts/help-functions +++ b/plugins/openresty-vhosts/help-functions @@ -30,6 +30,7 @@ fn-help-content() { openresty:report [] [], Displays an openresty report for one or more apps openresty:set (), Set or clear an openresty property for an app openresty:show-config , Display openresty compose config + openresty:label (), Show, set or clear an openresty label for an app openresty:start, Starts the openresty server openresty:stop, Stops the openresty server help_content diff --git a/plugins/openresty-vhosts/subcommands/label b/plugins/openresty-vhosts/subcommands/label new file mode 100755 index 000000000..b1a49be45 --- /dev/null +++ b/plugins/openresty-vhosts/subcommands/label @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +source "$PLUGIN_AVAILABLE_PATH/openresty-vhosts/command-functions" +set -eo pipefail +[[ $DOKKU_TRACE ]] && set -x + +cmd-openresty-label "$@" diff --git a/plugins/proxy/command-functions b/plugins/proxy/command-functions new file mode 100755 index 000000000..d38158421 --- /dev/null +++ b/plugins/proxy/command-functions @@ -0,0 +1,84 @@ +#!/usr/bin/env bash +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_AVAILABLE_PATH/proxy/functions" +set -eo pipefail +[[ $DOKKU_TRACE ]] && set -x + +cmd-proxy-label-show() { + declare desc="show a proxy label for an app" + declare cmd="proxy:label:show" + [[ "$1" == "$cmd" ]] && shift 1 + declare PROXY="$1" APP="$2" PASSED_LABEL_NAME="$3" + shift 2 + + if [[ -n "$PASSED_LABEL_NAME" ]]; then + fn-proxy-show-label "$PROXY" "$APP" "$PASSED_LABEL_NAME" + return + fi + + fn-proxy-display-labels "$PROXY" "$APP" + return 0 +} + +cmd-proxy-label-add() { + declare desc="adds container label to app for specified proxy" + declare PROXY="$1" APP="$2" PASSED_LABEL_NAME="$3" PASSED_LABEL_VALUE="$4" + if [[ -z "$PASSED_LABEL_NAME" ]]; then + dokku_log_fail "Please specify a container label for the app" + fi + + if [[ -z "$PASSED_LABEL_VALUE" ]]; then + dokku_log_fail "Please specify a value for the container label" + fi + + local proxy_labels_file_path="$(fn-proxy-get-labels-file-path "$PROXY" "$APP")" + touch "$proxy_labels_file_path" + cmd-proxy-label-remove "$PROXY" "$APP" "$PASSED_LABEL_NAME" >/dev/null + echo "--label '${PASSED_LABEL_NAME}=${PASSED_LABEL_VALUE}' " >>"$proxy_labels_file_path" + local all_proxy_labels="$(<"$proxy_labels_file_path")" + echo -e "${all_proxy_labels}" | sed '/^$/d' | sort -u >"$proxy_labels_file_path" +} + +cmd-proxy-label-remove() { + declare desc="removes container label from app for specified proxy" + declare PROXY="$1" APP="$2" PASSED_LABEL_NAME="$3" + + if [[ -z "$PASSED_LABEL_NAME" ]]; then + dokku_log_fail "Please specify a container label for the app" + fi + + local proxy_labels_file_path="$(fn-proxy-get-labels-file-path "$PROXY" "$APP")" + if [[ ! -s "$proxy_labels_file_path" ]]; then + return + fi + + local all_proxy_labels="$(<"$proxy_labels_file_path")" + local escaped_label_name="$(fn-proxy-escape-extended-sed "$PASSED_LABEL_NAME")" + local all_proxy_labels="$(echo -e "${all_proxy_labels}" | sed -E "s/^--label ['\"]${escaped_label_name}=.*\$//")" + echo -e "${all_proxy_labels}" | sed '/^$/d' | sort -u >"$proxy_labels_file_path" +} + +cmd-proxy-label() { + declare desc="manage proxy labels for an app" + declare cmd="proxy:label" + shift 1 # the command comes from the upstream plugin + declare PROXY="$1" ACTION="$2" APP="$3" PASSED_LABEL_NAME="$4" PASSED_LABEL_VALUE="$5" + + [[ -z "$PROXY" ]] && dokku_log_fail "Error invoking proxy:label command" + verify_app_name "$APP" + + if [[ -n "$PASSED_LABEL_NAME" ]] && [[ ! "$PASSED_LABEL_NAME" =~ ^$PROXY ]]; then + dokku_log_fail "Please specify a valid $PROXY label name for the app" + fi + + if [[ "$action" == "show" ]]; then + cmd-proxy-label-show "$PROXY" "$APP" "$PASSED_LABEL_NAME" + return 0 + elif [[ "$ACTION" == "set" ]]; then + cmd-proxy-label-add "$PROXY" "$APP" "$PASSED_LABEL_NAME" "$PASSED_LABEL_VALUE" + elif [[ "$action" == "unset" ]]; then + cmd-proxy-label-remove "$PROXY" "$APP" "$PASSED_LABEL_NAME" + else + dokku_log_fail "Please specify a valid action ('set', 'unset' or 'show')" + fi +} diff --git a/plugins/proxy/functions b/plugins/proxy/functions new file mode 100755 index 000000000..7a83e9677 --- /dev/null +++ b/plugins/proxy/functions @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +set -eo pipefail +[[ $DOKKU_TRACE ]] && set -x +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" + +fn-proxy-escape-extended-sed() { + # Escaped delimiter is '/' + local input="$1" + echo "$input" | sed -E 's#[][()\.^$?*+{}|/]#\\&#g' +} + +fn-proxy-report-label-overwrite() { + declare desc="overwrite proxy labels file with new labels" + declare LABELS="$1" PROXY_LABELS_FILE_PATH="$2" + + if [[ -f "$PROXY_LABELS_FILE_PATH" ]]; then + local DONE=false + until $DONE; do + local line + read -r line || local DONE=true + + [[ -z "$line" ]] && continue + + case "$line" in + \#*) + continue + ;; + + --label*) + local label_name="$(echo "$line" | sed -E "s/^--label ['\"]([^=]+)=.*/\1/")" + local escaped_label_name="$(fn-proxy-escape-extended-sed "$passed_label_name")" + local match="$(echo "$LABELS" | sed -E "s/.*--label ['\"]($escaped_label_name)=.*/\1/")" + if [[ -n "$match" ]]; then + dokku_log_warn "Dokku label \"$match\" will be overwritten by user-set proxy label." + fi + continue + ;; + + *) + dokku_log_warn "Invalid line '$line' in proxy label file $PROXY_FILE_PATH" + ;; + esac + done <"$PROXY_LABELS_FILE_PATH" + fi +} + +fn-proxy-get-labels-file-path() { + declare desc="return proxy labels config file path for specified proxy" + declare PROXY="$1" APP="$2" + local PROXY_FILE="${DOKKU_ROOT}/${APP}/PROXY_LABELS_${PROXY^^}" + + echo "$PROXY_FILE" +} + +fn-proxy-display-labels() { + declare desc="print user-set app container labels for specified proxy" + declare PROXY="$1" APP="$2" + local proxy_labels_file_path="$(fn-proxy-get-labels-file-path "$PROXY" "$APP")" + echo "${PROXY^} labels:" + sed -e 's/^/ /' "$proxy_labels_file_path" +} + +fn-proxy-show-label() { + declare desc="print single user-set app container label for specified proxy" + declare PROXY="$1" APP="$2" PASSED_LABEL_NAME="$3" + + local proxy_labels_file_path="$(fn-proxy-get-labels-file-path "$PROXY" "$APP")" + if [[ ! -s "$proxy_labels_file_path" ]]; then + return + fi + + local all_proxy_labels="$(<"$proxy_labels_file_path")" + local escaped_label_name="$(fn-proxy-escape-extended-sed "$passed_label_name")" + local proxy_label_value="$(echo -e "${all_proxy_labels}" | sed -E -n "s/^--label ['\"]${escaped_label_name}=(.*)['\"] \$/\1/p")" + + echo "$proxy_label_value" +} diff --git a/plugins/traefik-vhosts/command-functions b/plugins/traefik-vhosts/command-functions index 93f5429d5..5a9eb91ec 100755 --- a/plugins/traefik-vhosts/command-functions +++ b/plugins/traefik-vhosts/command-functions @@ -1,9 +1,20 @@ #!/usr/bin/env bash source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_AVAILABLE_PATH/proxy/command-functions" source "$PLUGIN_AVAILABLE_PATH/traefik-vhosts/internal-functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x +cmd-traefik-label() { + declare desc="set/unset/show container proxy labels" + declare cmd="traefik:label" + [[ "$1" == "$cmd" ]] && shift 1 + declare APP="$1" + + set -- traefik "$@" + cmd-proxy-label "$@" +} + cmd-traefik-report() { declare desc="displays a traefik report for one or more apps" declare cmd="traefik:report" diff --git a/plugins/traefik-vhosts/docker-args-process-deploy b/plugins/traefik-vhosts/docker-args-process-deploy index dfb8f075f..ea01d0c33 100755 --- a/plugins/traefik-vhosts/docker-args-process-deploy +++ b/plugins/traefik-vhosts/docker-args-process-deploy @@ -1,5 +1,6 @@ #!/usr/bin/env bash source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_AVAILABLE_PATH/proxy/functions" source "$PLUGIN_AVAILABLE_PATH/traefik-vhosts/internal-functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x @@ -130,6 +131,15 @@ trigger-traefik-vhosts-docker-args-process-deploy() { fi fi + local proxy_labels_file_path=$(fn-proxy-get-labels-file-path "$APP" traefik) + fn-proxy-report-label-overwrite "$output" "$proxy_labels_file_path" + + if [[ -f "$proxy_labels_file_path" ]]; then + local user_proxy_labels="$(<"$proxy_labels_file_path")" + user_proxy_labels="$(echo "$user_proxy_labels" | tr '\r\n' ' ')" + output="$output $user_proxy_labels" + fi + echo -n "$STDIN$output" } diff --git a/plugins/traefik-vhosts/help-functions b/plugins/traefik-vhosts/help-functions index 22ec4c1a8..3ceb61000 100755 --- a/plugins/traefik-vhosts/help-functions +++ b/plugins/traefik-vhosts/help-functions @@ -30,6 +30,7 @@ fn-help-content() { traefik:report [] [], Displays an traefik report for one or more apps traefik:set (), Set or clear an traefik property for an app traefik:show-config , Display traefik compose config + traefik:label (), Show, set or clear a traefik label for an app traefik:start, Starts the traefik server traefik:stop, Stops the traefik server help_content diff --git a/plugins/traefik-vhosts/subcommands/label b/plugins/traefik-vhosts/subcommands/label new file mode 100755 index 000000000..719f47b8b --- /dev/null +++ b/plugins/traefik-vhosts/subcommands/label @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +source "$PLUGIN_AVAILABLE_PATH/traefik-vhosts/command-functions" +set -eo pipefail +[[ $DOKKU_TRACE ]] && set -x + +cmd-traefik-label "$@"