#!/usr/bin/env bash source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_AVAILABLE_PATH/config/functions" set -eo pipefail [[ $DOKKU_TRACE ]] && set -x fn-domains-clear() { declare desc="clear all domains for one or more apps" declare APP="$1" if [[ "$APP" == "--all" ]]; then for APP in $(dokku_apps); do fn-domains-clear-app "$APP" done else fn-domains-clear-app "$APP" fi } fn-domains-clear-app() { declare desc="clear all domains for an app" declare APP="$1" local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST" rm -f "$APP_VHOST_PATH" plugn trigger post-domains-update "$APP" "clear" dokku_log_info1 "Cleared domains in $APP" } fn-domains-disable() { declare desc="disable domains/VHOST support" declare APP="$1" if [[ "$APP" == "--all" ]]; then for APP in $(dokku_apps); do domains_disable "$APP" done else domains_disable "$APP" fi } fn-domains-enable() { declare desc="enable domains/VHOST support" declare APP="$1" if [[ "$APP" == "--all" ]]; then for APP in $(dokku_apps); do domains_enable "$APP" done else domains_enable "$APP" fi } disable_app_vhost() { declare desc="disable vhost support for given application" declare APP=$1 RESTART_APP="$2" local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST" plugn trigger pre-disable-vhost "$APP" if [[ -f "$APP_VHOST_PATH" ]]; then dokku_log_info1 "App virtual host support disabled" rm -f "$APP_VHOST_PATH" fi [[ "$RESTART_APP" == "--no-restart" ]] && local CONFIG_SET_ARGS=$RESTART_APP DOKKU_QUIET_OUTPUT=1 config_set $CONFIG_SET_ARGS $APP NO_VHOST=1 if [[ "$RESTART_APP" == "--no-restart" ]]; then plugn trigger post-domains-update "$APP" "disable" fi } domains_setup() { declare desc="setup domains to default state" local APP="$1" local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST" local GLOBAL_VHOST_PATH="$DOKKU_ROOT/VHOST" local DEFAULT_VHOSTS="$(get_default_vhosts "$APP")" if [[ ! -f $APP_VHOST_PATH ]]; then if [[ -n "$DEFAULT_VHOSTS" ]]; then dokku_log_info1_quiet "Creating new app virtual host file..." echo "$DEFAULT_VHOSTS" >"$APP_VHOST_PATH" chown "${DOKKU_SYSTEM_USER}:${DOKKU_SYSTEM_GROUP}" "$APP_VHOST_PATH" else dokku_log_info1_quiet "Global server virtual host not set, disabling app vhost..." disable_app_vhost "$APP" --no-restart fi fi } domains_add() { declare desc="add list of domains to app" local APP="$1" local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST" shift 1 for DOMAIN in "$@"; do if ! (is_valid_hostname "$DOMAIN"); then dokku_log_fail "$DOMAIN is invalid. exiting..." fi done for DOMAIN in "$@"; do if grep -q --line-regexp --fixed-strings "$DOMAIN" "$APP_VHOST_PATH" 2>/dev/null; then dokku_log_info1 "Skipping: $DOMAIN already added to $APP" else echo "$DOMAIN" >>"$APP_VHOST_PATH" dokku_log_info1 "Added $DOMAIN to $APP" fi done if [[ "$(is_app_vhost_enabled "$APP")" == "false" ]]; then domains_enable "$APP" --no-restart fi plugn trigger post-domains-update "$APP" "add" "$@" } domains_remove() { declare desc="remove list of app domains" local APP="$1" local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST" shift 1 touch "$APP_VHOST_PATH" for DOMAIN in "$@"; do sed -i "\|^$DOMAIN\$|d" "$APP_VHOST_PATH" dokku_log_info1 "Removed $DOMAIN from $APP" done plugn trigger post-domains-update "$APP" "remove" "$@" } domains_set() { declare desc="set list of domains for app" local APP="$1" local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST" shift 1 touch "$APP_VHOST_PATH" for DOMAIN in "$@"; do if ! (is_valid_hostname "$DOMAIN"); then dokku_log_fail "$DOMAIN is invalid. exiting..." fi done echo "$*" | tr " " "\n" >"$APP_VHOST_PATH" dokku_log_info1 "Set $* for $APP" if [[ "$(is_app_vhost_enabled "$APP")" == "false" ]]; then domains_enable "$APP" --no-restart fi plugn trigger post-domains-update "$APP" "set" "$@" } domains_disable() { declare desc="disable domains/VHOST support" local APP="$1" local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST" touch "$APP_VHOST_PATH" if [[ "$(is_app_vhost_enabled "$APP")" == "true" ]]; then disable_app_vhost "$APP" --no-restart else dokku_log_info1 "Domains (VHOST) support is already disabled for app ($APP)" fi } domains_enable() { declare desc="enable domains/VHOST support" local APP="$1" RESTART_APP="$2" local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST" local DEFAULT_VHOSTS="$(get_default_vhosts "$APP")" touch "$APP_VHOST_PATH" if [[ "$(is_app_vhost_enabled "$APP")" == "false" ]]; then if [[ -n "$DEFAULT_VHOSTS" ]]; then echo "$DEFAULT_VHOSTS" >"$APP_VHOST_PATH" fi [[ "$RESTART_APP" == "--no-restart" ]] && local ENABLE_APP_VHOST_ARGS=$RESTART_APP enable_app_vhost "$APP" "$ENABLE_APP_VHOST_ARGS" else dokku_log_info1 "Domains (VHOST) support is already enabled for app ($APP)" fi } domains_add_global() { declare desc="add list of global domains" local GLOBAL_VHOST_PATH="$DOKKU_ROOT/VHOST" touch "$GLOBAL_VHOST_PATH" for DOMAIN in "$@"; do if ! (is_valid_hostname "$DOMAIN"); then dokku_log_fail "$DOMAIN is invalid. exiting..." fi done for DOMAIN in "$@"; do if grep -q --line-regexp --fixed-strings "$DOMAIN" "$GLOBAL_VHOST_PATH" 2>/dev/null; then dokku_log_info1 "Skipping $DOMAIN: already added" else echo "$DOMAIN" >>"$GLOBAL_VHOST_PATH" dokku_log_info1 "Added $DOMAIN" fi done } domains_clear_global() { declare desc="remove all domains" local GLOBAL_VHOST_PATH="$DOKKU_ROOT/VHOST" rm "$GLOBAL_VHOST_PATH" touch "$GLOBAL_VHOST_PATH" } domains_remove_global() { declare desc="remove list of domains" local GLOBAL_VHOST_PATH="$DOKKU_ROOT/VHOST" touch "$GLOBAL_VHOST_PATH" for DOMAIN in "$@"; do sed -i "\|^$DOMAIN\$|d" "$GLOBAL_VHOST_PATH" dokku_log_info1 "Removed $DOMAIN" done } domains_set_global() { declare desc="set list of global domains" local GLOBAL_VHOST_PATH="$DOKKU_ROOT/VHOST" touch "$GLOBAL_VHOST_PATH" for DOMAIN in "$@"; do if ! (is_valid_hostname "$DOMAIN"); then dokku_log_fail "$DOMAIN is invalid. exiting..." fi done echo "$*" | tr " " "\n" >"$GLOBAL_VHOST_PATH" dokku_log_info1 "Set $*" } enable_app_vhost() { declare desc="enable vhost support for given application" declare APP=$1 RESTART_APP="$2" plugn trigger pre-enable-vhost "$APP" [[ "$RESTART_APP" == "--no-restart" ]] && local CONFIG_SET_ARGS=$RESTART_APP DOKKU_QUIET_OUTPUT=1 config_set $CONFIG_SET_ARGS "$APP" NO_VHOST=0 if [[ "$RESTART_APP" == "--no-restart" ]]; then plugn trigger post-domains-update "$APP" "enable" fi } get_app_domains() { declare desc="return app domains" local APP=$1 local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST" if [[ "$(is_app_vhost_enabled "$APP")" == "true" ]] && [[ -f "$APP_VHOST_PATH" ]]; then cat "$APP_VHOST_PATH" fi } get_default_vhosts() { declare desc="return default vhosts" local APP="$1" local RE_IPV4="$(get_ipv4_regex)" local RE_IPV6="$(get_ipv6_regex)" if [[ "$(is_global_vhost_enabled)" == "true" ]]; then local VHOSTS=$(get_global_vhosts) while read -r VHOST; do if ! ([[ "$VHOST" =~ $RE_IPV4 ]] || [[ "$VHOST" =~ $RE_IPV6 ]]); then local SUBDOMAIN=${APP/%\.${VHOST}/} local hostname=$(: | plugn trigger nginx-hostname "$APP" "$SUBDOMAIN" "$VHOST") if [[ -z $hostname ]]; then if [[ "$APP" == *.* ]]; then local hostname="${APP/\//-}" else local hostname="${APP/\//-}.$VHOST" fi fi echo "$hostname" fi done <<<"$VHOSTS" fi } get_global_vhosts() { declare desc="return global vhosts" local GLOBAL_VHOST_PATH="$DOKKU_ROOT/VHOST" [[ -f "$GLOBAL_VHOST_PATH" ]] && local GLOBAL_VHOSTS=$(<"$GLOBAL_VHOST_PATH") echo "$GLOBAL_VHOSTS" } is_app_vhost_enabled() { declare desc="returns true or false if vhost support is enabled for a given application" local APP=$1 local NO_VHOST=$(config_get "$APP" NO_VHOST) local APP_VHOST_ENABLED=true if [[ "$NO_VHOST" == "1" ]]; then local APP_VHOST_ENABLED=false fi echo $APP_VHOST_ENABLED } is_global_vhost_enabled() { declare desc="returns true if we have a valid global vhost set; otherwise returns false" local GLOBAL_VHOSTS=$(get_global_vhosts) local GLOBAL_VHOSTS_ENABLED=false while read -r GLOBAL_VHOST; do if (is_valid_hostname "$GLOBAL_VHOST"); then local GLOBAL_VHOSTS_ENABLED=true break fi done <<<"$GLOBAL_VHOSTS" echo $GLOBAL_VHOSTS_ENABLED } is_valid_hostname() { declare desc="return 0 if argument is a valid hostname; else return 1" local hostname_string="${1,,}" local hostname_regex='^[a-z0-9\.\*-]*[a-z0-9\*-]$' if [[ "$hostname_string" == "_" ]]; then return 0 elif [[ $hostname_string =~ $hostname_regex ]]; then return 0 fi return 1 }