This standardization makes it somewhat easier to read stacktraces as the command names are all uniform, so it will be slightly easier to scan trace output.
242 lines
7.3 KiB
Bash
Executable File
242 lines
7.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -eo pipefail
|
|
[[ $DOKKU_TRACE ]] && set -x
|
|
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
|
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
|
|
|
|
cmd-nginx-report() {
|
|
declare desc="displays a nginx report for one or more apps"
|
|
local cmd="nginx:report"
|
|
local INSTALLED_APPS=$(dokku_apps)
|
|
local APP="$2" INFO_FLAG="$3"
|
|
|
|
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
|
|
INFO_FLAG="$APP"
|
|
APP=""
|
|
fi
|
|
|
|
if [[ -z "$APP" ]] && [[ -z "$INFO_FLAG" ]]; then
|
|
INFO_FLAG="true"
|
|
fi
|
|
|
|
if [[ -z "$APP" ]]; then
|
|
for app in $INSTALLED_APPS; do
|
|
cmd-nginx-report-single "$app" "$INFO_FLAG" | tee || true
|
|
done
|
|
else
|
|
cmd-nginx-report-single "$APP" "$INFO_FLAG"
|
|
fi
|
|
}
|
|
|
|
cmd-nginx-report-single() {
|
|
declare APP="$1" INFO_FLAG="$2"
|
|
if [[ "$INFO_FLAG" == "true" ]]; then
|
|
INFO_FLAG=""
|
|
fi
|
|
verify_app_name "$APP"
|
|
local flag_map=(
|
|
"--nginx-bind-address-ipv4: $(fn-plugin-property-get-default "nginx" "$APP" "bind-address-ipv4" "")"
|
|
"--nginx-bind-address-ipv6: $(fn-plugin-property-get-default "nginx" "$APP" "bind-address-ipv6" "::")"
|
|
"--nginx-hsts: $(fn-plugin-property-get-default "nginx" "$APP" "hsts" "true")"
|
|
"--nginx-hsts-include-subdomains: $(fn-plugin-property-get-default "nginx" "$APP" "hsts-include-subdomains" "true")"
|
|
"--nginx-hsts-max-age: $(fn-plugin-property-get-default "nginx" "$APP" "hsts-max-age" "15724800")"
|
|
"--nginx-hsts-preload: $(fn-plugin-property-get-default "nginx" "$APP" "hsts-preload" "false")"
|
|
)
|
|
|
|
if [[ -z "$INFO_FLAG" ]]; then
|
|
dokku_log_info2_quiet "${APP} nginx information"
|
|
for flag in "${flag_map[@]}"; do
|
|
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
|
|
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"
|
|
done
|
|
else
|
|
local match=false
|
|
local value_exists=false
|
|
for flag in "${flag_map[@]}"; do
|
|
valid_flags="${valid_flags} $(echo "$flag" | cut -d':' -f1)"
|
|
if [[ "$flag" == "${INFO_FLAG}:"* ]]; then
|
|
value=${flag#*: }
|
|
size="${#value}"
|
|
if [[ "$size" -ne 0 ]]; then
|
|
echo "$value" && match=true && value_exists=true
|
|
else
|
|
match=true
|
|
fi
|
|
fi
|
|
done
|
|
[[ "$match" == "true" ]] || dokku_log_fail "Invalid flag passed, valid flags:${valid_flags}"
|
|
[[ "$value_exists" == "true" ]] || dokku_log_fail "not deployed"
|
|
fi
|
|
}
|
|
|
|
fn-nginx-vhosts-manage-hsts() {
|
|
declare APP="$1" SSL_ENABLED="$2"
|
|
local HSTS="$(fn-plugin-property-get-default "nginx" "$APP" "hsts" "true")"
|
|
local HSTS_INCLUDE_SUBDOMAINS="$(fn-plugin-property-get-default "nginx" "$APP" "hsts-include-subdomains" "true")"
|
|
local HSTS_MAX_AGE="$(fn-plugin-property-get-default "nginx" "$APP" "hsts-max-age" "15724800")"
|
|
local HSTS_PRELOAD="$(fn-plugin-property-get-default "nginx" "$APP" "hsts-preload" "false")"
|
|
local NGINX_HSTS_CONF="$DOKKU_ROOT/$APP/nginx.conf.d/hsts.conf"
|
|
local HSTS_TEMPLATE="$PLUGIN_AVAILABLE_PATH/nginx-vhosts/templates/hsts.conf.sigil"
|
|
|
|
if [[ "$HSTS" == "false" ]] || [[ "$SSL_ENABLED" != "true" ]]; then
|
|
rm -rf "$NGINX_HSTS_CONF"
|
|
return
|
|
fi
|
|
|
|
dokku_log_verbose_quiet "Enabling HSTS"
|
|
local HSTS_HEADERS=""
|
|
if [[ -n "$HSTS_MAX_AGE" ]]; then
|
|
HSTS_HEADERS="max-age=$HSTS_MAX_AGE"
|
|
fi
|
|
|
|
if [[ "$HSTS_INCLUDE_SUBDOMAINS" == "true" ]]; then
|
|
HSTS_HEADERS+="; includeSubdomains"
|
|
fi
|
|
|
|
if [[ "$HSTS_PRELOAD" == "true" ]]; then
|
|
HSTS_HEADERS+="; preload"
|
|
fi
|
|
|
|
mkdir -p "$DOKKU_ROOT/$APP/nginx.conf.d"
|
|
sigil -f "$HSTS_TEMPLATE" HSTS_HEADERS="$HSTS_HEADERS" | cat -s >"$NGINX_HSTS_CONF"
|
|
}
|
|
|
|
fn-nginx-vhosts-uses-openresty() {
|
|
declare desc="returns whether openresty is in use or not"
|
|
|
|
if [[ -x /usr/bin/openresty ]]; then
|
|
return
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
fn-nginx-vhosts-nginx-location() {
|
|
declare desc="check that nginx is at the expected location and return it"
|
|
local NGINX_LOCATION
|
|
|
|
NGINX_LOCATION=$(which nginx 2>/dev/null)
|
|
if [[ -z "$NGINX_LOCATION" ]]; then
|
|
NGINX_LOCATION="/usr/sbin/nginx"
|
|
fi
|
|
|
|
if fn-nginx-vhosts-uses-openresty; then
|
|
NGINX_LOCATION="/usr/bin/openresty"
|
|
fi
|
|
|
|
if [[ ! -x "$NGINX_LOCATION" ]]; then
|
|
dokku_log_fail "Could not find nginx binary in \$PATH or at '${NGINX_LOCATION}'."
|
|
fi
|
|
|
|
echo "$NGINX_LOCATION"
|
|
}
|
|
|
|
fn-nginx-vhosts-nginx-init-cmd() {
|
|
declare desc="start nginx for given distros"
|
|
declare CMD="$1"
|
|
local NGINX_INIT_NAME
|
|
|
|
NGINX_INIT_NAME=nginx
|
|
if fn-nginx-vhosts-uses-openresty; then
|
|
NGINX_INIT_NAME=openresty
|
|
fi
|
|
|
|
case "$DOKKU_DISTRO" in
|
|
debian)
|
|
sudo /usr/sbin/invoke-rc.d "$NGINX_INIT_NAME" "$CMD"
|
|
;;
|
|
|
|
ubuntu)
|
|
# support docker-based installations
|
|
if [[ -x /usr/bin/sv ]]; then
|
|
sudo /usr/bin/sv "$CMD" "$NGINX_INIT_NAME"
|
|
else
|
|
sudo "/etc/init.d/$NGINX_INIT_NAME" "$CMD"
|
|
fi
|
|
;;
|
|
|
|
opensuse)
|
|
sudo /sbin/service "$NGINX_INIT_NAME" "$CMD"
|
|
;;
|
|
|
|
arch | centos | rhel)
|
|
sudo /usr/bin/systemctl "$CMD" "$NGINX_INIT_NAME"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
nginx_vhosts_validate_single_func() {
|
|
declare APP="$1" FLAG="$2"
|
|
local NGINX_CONF="$DOKKU_ROOT/$APP/nginx.conf"
|
|
|
|
if [[ ! -f "$NGINX_CONF" ]]; then
|
|
dokku_log_warn_quiet "No nginx config found for ${APP}"
|
|
return
|
|
fi
|
|
|
|
if nginx_vhosts_is_valid_nginx_config_func "$APP"; then
|
|
return
|
|
fi
|
|
|
|
dokku_log_warn "Failed to validate nginx config for ${APP}. Contents below..."
|
|
cat "$NGINX_CONF"
|
|
|
|
if [[ "$FLAG" == "--clean" ]]; then
|
|
nginx_vhosts_conf_clean_func "$APP"
|
|
fi
|
|
}
|
|
|
|
nginx_vhosts_is_valid_nginx_config_func() {
|
|
declare desc="checks if an app has a valid nginx config"
|
|
declare APP="$1"
|
|
local VALIDATE_TEMPLATE="$PLUGIN_AVAILABLE_PATH/nginx-vhosts/templates/validate.conf.sigil"
|
|
local TMP_OUTPUT=$(mktemp "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
|
|
trap "rm -rf '$TMP_OUTPUT' >/dev/null" RETURN INT TERM EXIT
|
|
|
|
sigil -f "$VALIDATE_TEMPLATE" NGINX_CONF="$DOKKU_ROOT/$APP/nginx.conf" | cat -s >"$TMP_OUTPUT"
|
|
sudo "$NGINX_LOCATION" -t -c "$TMP_OUTPUT" 2>/dev/null
|
|
}
|
|
|
|
nginx_vhosts_conf_clean_func() {
|
|
declare APP="$1"
|
|
local NGINX_CONF="$DOKKU_ROOT/$APP/nginx.conf"
|
|
dokku_log_warn "Removing invalid nginx file"
|
|
rm -f "$NGINX_CONF"
|
|
}
|
|
|
|
nginx_vhosts_help_content_func() {
|
|
declare desc="return nginx plugin help content"
|
|
cat <<help_content
|
|
nginx:access-logs <app> [-t], Show the nginx access logs for an application (-t follows)
|
|
nginx:build-config <app>, (Re)builds nginx config for given app
|
|
nginx:error-logs <app> [-t], Show the nginx error logs for an application (-t follows)
|
|
nginx:report [<app>] [<flag>], Displays an nginx report for one or more apps
|
|
nginx:set <app> <property> (<value>), Set or clear an nginx property for an app
|
|
nginx:show-conf <app>, Display app nginx config
|
|
nginx:validate [<app>] [--clean], Validates and optionally cleans up invalid nginx configurations
|
|
help_content
|
|
}
|
|
|
|
cmd-nginx-vhosts-help() {
|
|
if [[ $1 == "nginx:help" ]]; then
|
|
echo -e 'Usage: dokku nginx[:COMMAND]'
|
|
echo ''
|
|
echo 'Interact with Dokku'"'"'s Nginx proxy.'
|
|
echo ''
|
|
echo 'Additional commands:'
|
|
nginx_vhosts_help_content_func | sort | column -c2 -t -s,
|
|
elif [[ $(ps -o command= $PPID) == *"--all"* ]]; then
|
|
nginx_vhosts_help_content_func
|
|
else
|
|
cat <<help_desc
|
|
nginx, Interact with Dokku's Nginx proxy
|
|
help_desc
|
|
fi
|
|
}
|
|
|
|
nginx_clear_config() {
|
|
declare desc="Remove the nginx conf file"
|
|
declare APP="$1"
|
|
rm -f "$DOKKU_ROOT/$APP/nginx.conf"
|
|
}
|