From 0d4560177a34a99d9561b2274048defbde808f64 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 15 Jul 2016 02:51:31 -0400 Subject: [PATCH] Properly remap http port 80 mappings to https 443 when adding an ssl certificate Rather than removing all port mappings, we simply remap port 80 mappings to 443. The previous behavior would remove custom port mappings for all applications and reset them on any certificate change, preventing automation from plugins such as letsencrypt. While this behavior doesn't matter for buildpack deploys - which only expose a single port on container port 5000 - Dockerfile deploys would frequently be affected by such a change, requiring a remapping of all custom ports. This commit also standardizes on the method used to source the proxy functions --- plugins/certs/subcommands/add | 3 -- plugins/common/functions | 2 +- plugins/nginx-vhosts/post-certs-update | 7 ++- plugins/nginx-vhosts/proxy-disable | 2 +- plugins/nginx-vhosts/proxy-enable | 2 +- plugins/proxy/functions | 60 ++++++++++++++++++++++++++ plugins/proxy/subcommands/ports | 2 +- plugins/proxy/subcommands/ports-add | 11 +---- plugins/proxy/subcommands/ports-remove | 27 +++--------- 9 files changed, 77 insertions(+), 39 deletions(-) diff --git a/plugins/certs/subcommands/add b/plugins/certs/subcommands/add index 8a539233b..07601378c 100755 --- a/plugins/certs/subcommands/add +++ b/plugins/certs/subcommands/add @@ -38,7 +38,6 @@ certs_set() { if is_file_import "$CRT_FILE" "$KEY_FILE"; then # importing from file true - elif is_tar_import; then local CERTS_SET_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_certs_set.XXXX") pushd "$CERTS_SET_TMP_WORK_DIR" &> /dev/null @@ -64,10 +63,8 @@ certs_set() { else local KEY_FILE=$KEY_FILE_SEARCH fi - else dokku_log_fail "Tar archive containing server.crt and server.key expected on stdin" - fi mkdir -p "$APP_SSL_PATH" diff --git a/plugins/common/functions b/plugins/common/functions index 459f7c236..6d3a339eb 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -524,7 +524,7 @@ dokku_deploy_cmd() { local cmd="deploy" source "$PLUGIN_AVAILABLE_PATH/checks/functions" source "$PLUGIN_AVAILABLE_PATH/config/functions" - source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions" + source "$PLUGIN_AVAILABLE_PATH/proxy/functions" [[ -z $1 ]] && dokku_log_fail "Please specify an app to deploy" local APP="$1"; local IMAGE_TAG="$2"; local IMAGE=$(get_deploying_app_image_name "$APP" "$IMAGE_TAG") diff --git a/plugins/nginx-vhosts/post-certs-update b/plugins/nginx-vhosts/post-certs-update index 22756ea18..3a391d7b5 100755 --- a/plugins/nginx-vhosts/post-certs-update +++ b/plugins/nginx-vhosts/post-certs-update @@ -20,7 +20,12 @@ nginx_post_certs_update() { config_unset --no-restart "$APP" DOKKU_NGINX_SSL_PORT fi if [[ "$DOKKU_PROXY_PORT_MAP" == *http:80:* ]]; then - config_unset --no-restart "$APP" DOKKU_PROXY_PORT_MAP + # shellcheck disable=SC2046 + remove_proxy_ports "$APP" $(filter_app_proxy_ports "$APP" "https" "443") + # shellcheck disable=SC2046 + for port_map in $(filter_app_proxy_ports "$APP" "http" "80"); do + add_proxy_ports "$APP" "https:443:$(cut -d ':' -f3 <<< "$port_map")" + done fi fi } diff --git a/plugins/nginx-vhosts/proxy-disable b/plugins/nginx-vhosts/proxy-disable index 512863078..681c860c2 100755 --- a/plugins/nginx-vhosts/proxy-disable +++ b/plugins/nginx-vhosts/proxy-disable @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" -source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions" +source "$PLUGIN_AVAILABLE_PATH/proxy/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/ps/functions" nginx_proxy_disable() { diff --git a/plugins/nginx-vhosts/proxy-enable b/plugins/nginx-vhosts/proxy-enable index a4fe26edd..366f94ed8 100755 --- a/plugins/nginx-vhosts/proxy-enable +++ b/plugins/nginx-vhosts/proxy-enable @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" -source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions" +source "$PLUGIN_AVAILABLE_PATH/proxy/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/ps/functions" nginx_proxy_enable() { diff --git a/plugins/proxy/functions b/plugins/proxy/functions index 010136719..d7d3b1a2f 100755 --- a/plugins/proxy/functions +++ b/plugins/proxy/functions @@ -40,3 +40,63 @@ list_app_proxy_ports() { dokku_log_fail "No port mappings configured for app ($APP)" fi } + +filter_app_proxy_ports() { + declare desc="list proxy port mappings for an app that start with a particular scheme and a host port" + local APP="$1"; verify_app_name "$APP" + local SCHEME="$2" HOST_PORT="$3" + local PROXY_PORT_MAP="$(config_get "$APP" DOKKU_PROXY_PORT_MAP || true)" + + if [[ -n "$PROXY_PORT_MAP" ]]; then + local port_map + for port_map in $PROXY_PORT_MAP; do + local scheme="$(cut -d ':' -f1 <<< "$port_map")" + local host_port="$(cut -d ':' -f2 <<< "$port_map")" + if [[ "$scheme" == "$SCHEME" ]] && [[ "$host_port" == "$HOST_PORT" ]]; then + echo "$port_map" + fi + done + fi +} + +add_proxy_ports() { + declare desc="add proxy port mappings from an app" + local APP="$1" + local PROXY_PORT_MAP="$(config_get "$APP" DOKKU_PROXY_PORT_MAP || true)" + shift 1 + + local INPUT_PORTS="$*" + if [[ -n "$INPUT_PORTS" ]]; then + PROXY_PORT_MAP="$(merge_dedupe_list "$PROXY_PORT_MAP $INPUT_PORTS" " ")" + config_set --no-restart "$APP" DOKKU_PROXY_PORT_MAP="$PROXY_PORT_MAP" + else + dokku proxy:help + dokku_log_fail "No port mapping specified. Exiting..." + fi +} + +remove_proxy_ports() { + declare desc="remove specific proxy port mappings from an app" + local APP="$1" + local PROXY_PORT_MAP="$(config_get "$APP" DOKKU_PROXY_PORT_MAP || true)" + local RE_PORT='^[0-9]+$' + shift 1 + + local INPUT_PORTS="$*" + local port + PROXY_PORT_MAP=" $PROXY_PORT_MAP " + for port in $INPUT_PORTS; do + if [[ "$port" =~ $RE_PORT ]]; then + PROXY_PORT_MAP="$(sed -r "s/[[:alnum:]]+:$port:[[:alnum:]]+//g" <<< "$PROXY_PORT_MAP")" + else + PROXY_PORT_MAP="$(sed -r "s/ $port / /g" <<< "$PROXY_PORT_MAP")" + fi + done + PROXY_PORT_MAP="$(echo "$PROXY_PORT_MAP" | xargs)" + PROXY_PORT_MAP="$(merge_dedupe_list "$PROXY_PORT_MAP" " ")" + if [[ -n "$PROXY_PORT_MAP" ]]; then + config_set --no-restart "$APP" DOKKU_PROXY_PORT_MAP="$PROXY_PORT_MAP" + else + config_unset --no-restart "$APP" DOKKU_PROXY_PORT_MAP + fi +} diff --git a/plugins/proxy/subcommands/ports b/plugins/proxy/subcommands/ports index 47a1a6cab..912f4b99f 100755 --- a/plugins/proxy/subcommands/ports +++ b/plugins/proxy/subcommands/ports @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" -source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions" +source "$PLUGIN_AVAILABLE_PATH/proxy/functions" source "$PLUGIN_AVAILABLE_PATH/config/functions" proxy_ports_cmd() { diff --git a/plugins/proxy/subcommands/ports-add b/plugins/proxy/subcommands/ports-add index 911da22b2..ce7f8c226 100755 --- a/plugins/proxy/subcommands/ports-add +++ b/plugins/proxy/subcommands/ports-add @@ -2,22 +2,15 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_AVAILABLE_PATH/config/functions" +source "$PLUGIN_AVAILABLE_PATH/proxy/functions" proxy_ports_add_cmd() { declare desc="add proxy port mappings from an app" local cmd="proxy:add" local APP="$2"; verify_app_name "$APP" - local PROXY_PORT_MAP="$(config_get "$APP" DOKKU_PROXY_PORT_MAP || true)" shift 2 - local INPUT_PORTS="$*" - if [[ -n "$INPUT_PORTS" ]]; then - PROXY_PORT_MAP="$(merge_dedupe_list "$PROXY_PORT_MAP $INPUT_PORTS" " ")" - config_set --no-restart "$APP" DOKKU_PROXY_PORT_MAP="$PROXY_PORT_MAP" - else - dokku proxy:help - dokku_log_fail "No port mapping specified. Exiting..." - fi + add_proxy_ports "$APP" "$@" plugn trigger post-proxy-ports-update "$APP" "add" } diff --git a/plugins/proxy/subcommands/ports-remove b/plugins/proxy/subcommands/ports-remove index 0d73df5ca..267c86654 100755 --- a/plugins/proxy/subcommands/ports-remove +++ b/plugins/proxy/subcommands/ports-remove @@ -1,41 +1,24 @@ #!/usr/bin/env bash set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" -source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions" +source "$PLUGIN_AVAILABLE_PATH/proxy/functions" source "$PLUGIN_AVAILABLE_PATH/config/functions" proxy_ports_remove_cmd() { declare desc="remove specific proxy port mappings from an app" local cmd="proxy:ports-remove" local APP="$2"; verify_app_name "$APP" - local PROXY_PORT_MAP="$(config_get "$APP" DOKKU_PROXY_PORT_MAP || true)" - local RE_PORT='^[0-9]+$' shift 2 local INPUT_PORTS="$*" - if [[ -n "$INPUT_PORTS" ]]; then - local port - PROXY_PORT_MAP=" $PROXY_PORT_MAP " - for port in $INPUT_PORTS; do - if [[ "$port" =~ $RE_PORT ]]; then - PROXY_PORT_MAP="$(sed -r "s/[[:alnum:]]+:$port:[[:alnum:]]+//g" <<< "$PROXY_PORT_MAP")" - else - PROXY_PORT_MAP="$(sed -r "s/ $port / /g" <<< "$PROXY_PORT_MAP")" - fi - done - PROXY_PORT_MAP="$(echo "$PROXY_PORT_MAP" | xargs)" - PROXY_PORT_MAP="$(merge_dedupe_list "$PROXY_PORT_MAP" " ")" - if [[ -n "$PROXY_PORT_MAP" ]]; then - config_set --no-restart "$APP" DOKKU_PROXY_PORT_MAP="$PROXY_PORT_MAP" - else - config_unset --no-restart "$APP" DOKKU_PROXY_PORT_MAP - fi - plugn trigger post-proxy-ports-update "$APP" "remove" - else + if [[ -z "$INPUT_PORTS" ]]; then dokku_log_warn "No port mapping specified. Please supply a valid configured host port" list_app_proxy_ports "$APP" dokku_log_fail "exiting..." fi + + remove_proxy_ports "$APP" "$@" + plugn trigger post-proxy-ports-update "$APP" "remove" } proxy_ports_remove_cmd "$@"