refactor: deprecate proxy-configure-ports plugin trigger in favor of ports-configure
This also rewrites the logic to be in golang, which will make it easier to refactor portions of it to use the property system going forward.
This commit is contained in:
1
plugins/20_events/ports-configure
Symbolic link
1
plugins/20_events/ports-configure
Symbolic link
@@ -0,0 +1 @@
|
||||
hook
|
||||
@@ -30,7 +30,7 @@ trigger-caddy-vhosts-docker-args-process-deploy() {
|
||||
fi
|
||||
|
||||
# ensure we have a port mapping
|
||||
plugn trigger proxy-configure-ports "$APP"
|
||||
plugn trigger ports-configure "$APP"
|
||||
|
||||
# gather port mapping information
|
||||
# we only support proxying a single port for http and https listeners
|
||||
|
||||
6
plugins/common/ports-get-available
Executable file
6
plugins/common/ports-get-available
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
get_available_port "$@"
|
||||
@@ -33,7 +33,7 @@ trigger-haproxy-vhosts-docker-args-process-deploy() {
|
||||
plugn trigger domains-setup "$APP" >/dev/null
|
||||
|
||||
# ensure we have a port mapping
|
||||
plugn trigger proxy-configure-ports "$APP"
|
||||
plugn trigger ports-configure "$APP"
|
||||
|
||||
# gather port mapping information
|
||||
# we only support proxying a single port for http and https listeners
|
||||
|
||||
@@ -318,7 +318,7 @@ nginx_build_config() {
|
||||
fi
|
||||
|
||||
# setup nginx listen ports
|
||||
plugn trigger proxy-configure-ports "$APP"
|
||||
plugn trigger ports-configure "$APP"
|
||||
local PROXY_PORT=$(config_get "$APP" DOKKU_PROXY_PORT)
|
||||
local PROXY_SSL_PORT=$(config_get "$APP" DOKKU_PROXY_SSL_PORT)
|
||||
local PROXY_PORT_MAP=$(plugn trigger ports-get "$APP")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
SUBCOMMANDS = subcommands/list subcommands/add subcommands/clear subcommands/remove subcommands/set subcommands/report
|
||||
TRIGGERS = triggers/ports-clear triggers/ports-dockerfile-raw-tcp-ports triggers/ports-get triggers/ports-get-available triggers/post-certs-remove triggers/post-certs-update triggers/report
|
||||
TRIGGERS = triggers/ports-clear triggers/ports-configure triggers/ports-dockerfile-raw-tcp-ports triggers/ports-get triggers/ports-get-available triggers/post-certs-remove triggers/post-certs-update triggers/report
|
||||
BUILD = commands subcommands triggers
|
||||
PLUGIN_NAME = ports
|
||||
|
||||
|
||||
@@ -28,6 +28,12 @@ func clearPorts(appName string) error {
|
||||
}, map[string]string{"DOKKU_QUIET_OUTPUT": "1"})
|
||||
}
|
||||
|
||||
func doesCertExist(appName string) bool {
|
||||
b, _ := common.PlugnTriggerOutput("certs-exists", []string{appName}...)
|
||||
certsExists := strings.TrimSpace(string(b[:]))
|
||||
return certsExists == "true"
|
||||
}
|
||||
|
||||
func filterAppPortMaps(appName string, scheme string, hostPort int) []PortMap {
|
||||
var filteredPortMaps []PortMap
|
||||
for _, portMap := range getPortMaps(appName) {
|
||||
@@ -90,12 +96,59 @@ func getDockerfileRawTCPPorts(appName string) []int {
|
||||
return ports
|
||||
}
|
||||
|
||||
func getGlobalProxyPort() int {
|
||||
port := 0
|
||||
b, _ := common.PlugnTriggerOutput("config-get-global", []string{"DOKKU_PROXY_PORT"}...)
|
||||
if intVar, err := strconv.Atoi(strings.TrimSpace(string(b[:]))); err == nil {
|
||||
port = intVar
|
||||
}
|
||||
|
||||
return port
|
||||
}
|
||||
|
||||
func getGlobalProxySSLPort() int {
|
||||
port := 0
|
||||
b, _ := common.PlugnTriggerOutput("config-get-global", []string{"DOKKU_PROXY_SSL_PORT"}...)
|
||||
if intVar, err := strconv.Atoi(strings.TrimSpace(string(b[:]))); err == nil {
|
||||
port = intVar
|
||||
}
|
||||
|
||||
return port
|
||||
}
|
||||
|
||||
func getPortMaps(appName string) []PortMap {
|
||||
value := config.GetWithDefault(appName, "DOKKU_PROXY_PORT_MAP", "")
|
||||
portMaps, _ := parsePortMapString(value)
|
||||
return portMaps
|
||||
}
|
||||
|
||||
func getProxyPort(appName string) int {
|
||||
port := 0
|
||||
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_PROXY_PORT"}...)
|
||||
if intVar, err := strconv.Atoi(strings.TrimSpace(string(b[:]))); err == nil {
|
||||
port = intVar
|
||||
}
|
||||
|
||||
return port
|
||||
}
|
||||
|
||||
func getProxySSLPort(appName string) int {
|
||||
port := 0
|
||||
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_PROXY_SSL_PORT"}...)
|
||||
if intVar, err := strconv.Atoi(strings.TrimSpace(string(b[:]))); err == nil {
|
||||
port = intVar
|
||||
}
|
||||
|
||||
return port
|
||||
}
|
||||
|
||||
func isAppVhostEnabled(appName string) bool {
|
||||
if err := common.PlugnTrigger("domains-vhost-enabled", []string{appName}...); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func inRange(value int, min int, max int) bool {
|
||||
return min < value && value < max
|
||||
}
|
||||
@@ -223,11 +276,13 @@ func setPortMaps(appName string, portMaps []PortMap) error {
|
||||
value = append(value, portMap.String())
|
||||
}
|
||||
|
||||
sort.Strings(value)
|
||||
entries := map[string]string{
|
||||
"DOKKU_PROXY_PORT_MAP": strings.Join(value, " "),
|
||||
}
|
||||
return config.SetMany(appName, entries, false)
|
||||
return common.EnvWrap(func() error {
|
||||
sort.Strings(value)
|
||||
entries := map[string]string{
|
||||
"DOKKU_PROXY_PORT_MAP": strings.Join(value, " "),
|
||||
}
|
||||
return config.SetMany(appName, entries, false)
|
||||
}, map[string]string{"DOKKU_QUIET_OUTPUT": "1"})
|
||||
}
|
||||
|
||||
func uniquePortMaps(portMaps []PortMap) []PortMap {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/config/functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
@@ -8,58 +7,9 @@ trigger-ports-proxy-configure-ports() {
|
||||
declare desc="ports proxy-configure-ports plugin trigger"
|
||||
declare trigger="proxy-configure-ports"
|
||||
declare APP="$1"
|
||||
local RAW_TCP_PORTS="$(plugn trigger ports-dockerfile-raw-tcp-ports "$APP" | xargs)"
|
||||
local DOKKU_PROXY_PORT=$(config_get "$APP" DOKKU_PROXY_PORT)
|
||||
local DOKKU_PROXY_SSL_PORT=$(config_get "$APP" DOKKU_PROXY_SSL_PORT)
|
||||
local DOKKU_PROXY_PORT_MAP=$(config_get "$APP" DOKKU_PROXY_PORT_MAP)
|
||||
local IS_APP_VHOST_ENABLED=true
|
||||
local UPSTREAM_PORT="5000"
|
||||
|
||||
plugn trigger domains-vhost-enabled "$APP" 2>/dev/null || IS_APP_VHOST_ENABLED=false
|
||||
|
||||
if [[ -z "$DOKKU_PROXY_PORT" ]] && [[ -z "$RAW_TCP_PORTS" ]]; then
|
||||
if [[ "$IS_APP_VHOST_ENABLED" == "false" ]]; then
|
||||
dokku_log_info1 "No port set, setting to random open high port"
|
||||
local PROXY_PORT=$(plugn trigger ports-get-available)
|
||||
else
|
||||
local PROXY_PORT=$(config_get --global DOKKU_PROXY_PORT)
|
||||
PROXY_PORT=${PROXY_PORT:=80}
|
||||
fi
|
||||
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_PROXY_PORT="$PROXY_PORT"
|
||||
fi
|
||||
if [[ -z "$DOKKU_PROXY_SSL_PORT" ]]; then
|
||||
if [[ "$(plugn trigger certs-exists "$APP")" == "true" ]]; then
|
||||
local PROXY_SSL_PORT=$(config_get --global DOKKU_PROXY_SSL_PORT)
|
||||
PROXY_SSL_PORT=${PROXY_SSL_PORT:=443}
|
||||
if [[ -z "$RAW_TCP_PORTS" ]] && [[ "$IS_APP_VHOST_ENABLED" == "false" ]]; then
|
||||
dokku_log_info1 "No ssl port set, setting to random open high port"
|
||||
PROXY_SSL_PORT=$(plugn trigger ports-get-available)
|
||||
fi
|
||||
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_PROXY_SSL_PORT="$PROXY_SSL_PORT"
|
||||
fi
|
||||
fi
|
||||
if [[ -z "$DOKKU_PROXY_PORT_MAP" ]]; then
|
||||
if [[ -n "$RAW_TCP_PORTS" ]]; then
|
||||
local RAW_TCP_PORT
|
||||
for RAW_TCP_PORT in $RAW_TCP_PORTS; do
|
||||
local PROXY_PORT_MAP+=" http:${RAW_TCP_PORT}:${RAW_TCP_PORT} "
|
||||
done
|
||||
else
|
||||
local PROXY_PORT=${PROXY_PORT:-$DOKKU_PROXY_PORT}
|
||||
local PROXY_SSL_PORT=${PROXY_SSL_PORT:-$DOKKU_PROXY_SSL_PORT}
|
||||
[[ -f "$DOKKU_ROOT/$APP/PORT.web.1" ]] && local UPSTREAM_PORT="$(<"$DOKKU_ROOT/$APP/PORT.web.1")"
|
||||
if [[ -n "$PROXY_PORT" ]] && [[ -n "$PROXY_SSL_PORT" ]]; then
|
||||
local PROXY_PORT_MAP+=" http:${PROXY_PORT}:$UPSTREAM_PORT https:${PROXY_SSL_PORT}:$UPSTREAM_PORT "
|
||||
elif [[ -n "$PROXY_PORT" ]]; then
|
||||
local PROXY_PORT_MAP+=" http:${PROXY_PORT}:$UPSTREAM_PORT "
|
||||
fi
|
||||
fi
|
||||
if [[ -n "$PROXY_PORT_MAP" ]]; then
|
||||
local PROXY_PORT_MAP="$(echo "$PROXY_PORT_MAP" | xargs)"
|
||||
local PROXY_PORT_MAP+=" $(merge_dedupe_list "$(remove_val_from_list "$PORT_MAP" "$DOKKU_PROXY_PORT_MAP" " ")" " ") "
|
||||
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_PROXY_PORT_MAP="$PROXY_PORT_MAP"
|
||||
fi
|
||||
fi
|
||||
dokku_log_warn "Deprecated: please use the 'ports-configure' plugin trigger instead"
|
||||
plugn trigger ports-configure "$APP"
|
||||
}
|
||||
|
||||
trigger-ports-proxy-configure-ports "$@"
|
||||
|
||||
@@ -21,6 +21,9 @@ func main() {
|
||||
case "ports-clear":
|
||||
appName := flag.Arg(0)
|
||||
err = ports.TriggerPortsClear(appName)
|
||||
case "ports-configure":
|
||||
appName := flag.Arg(0)
|
||||
err = ports.TriggerPortsConfigure(appName)
|
||||
case "ports-dockerfile-raw-tcp-ports":
|
||||
appName := flag.Arg(0)
|
||||
err = ports.TriggerPortsDockerfileRawTCPPorts(appName)
|
||||
|
||||
@@ -2,6 +2,8 @@ package ports
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
"github.com/dokku/dokku/plugins/config"
|
||||
@@ -12,6 +14,110 @@ func TriggerPortsClear(appName string) error {
|
||||
return clearPorts(appName)
|
||||
}
|
||||
|
||||
// TriggerPortsConfigure ensures we have a port mapping
|
||||
func TriggerPortsConfigure(appName string) error {
|
||||
rawTCPPorts := getDockerfileRawTCPPorts(appName)
|
||||
|
||||
dokkuProxyPort := getProxyPort(appName)
|
||||
dokkuProxySSLPort := getProxySSLPort(appName)
|
||||
portMaps := getPortMaps(appName)
|
||||
|
||||
vhostEnabled := isAppVhostEnabled(appName)
|
||||
|
||||
if dokkuProxyPort == 0 && len(rawTCPPorts) == 0 {
|
||||
proxyPort := 80
|
||||
if !vhostEnabled {
|
||||
common.LogInfo1("No port set, setting to random open high port")
|
||||
proxyPort = getAvailablePort()
|
||||
} else {
|
||||
proxyPort = getGlobalProxyPort()
|
||||
}
|
||||
|
||||
if proxyPort == 0 {
|
||||
proxyPort = 80
|
||||
}
|
||||
|
||||
dokkuProxyPort = proxyPort
|
||||
err := common.EnvWrap(func() error {
|
||||
entries := map[string]string{
|
||||
"DOKKU_PROXY_PORT": fmt.Sprint(proxyPort),
|
||||
}
|
||||
return config.SetMany(appName, entries, false)
|
||||
}, map[string]string{"DOKKU_QUIET_OUTPUT": "1"})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if dokkuProxySSLPort == 0 {
|
||||
if doesCertExist(appName) {
|
||||
proxySSLPort := getGlobalProxySSLPort()
|
||||
if proxySSLPort == 0 {
|
||||
proxySSLPort = 443
|
||||
}
|
||||
|
||||
if len(rawTCPPorts) == 0 && !vhostEnabled {
|
||||
common.LogInfo1("No ssl port set, setting to random open high port")
|
||||
proxySSLPort = getAvailablePort()
|
||||
}
|
||||
|
||||
dokkuProxySSLPort = proxySSLPort
|
||||
err := common.EnvWrap(func() error {
|
||||
entries := map[string]string{
|
||||
"DOKKU_PROXY_SSL_PORT": fmt.Sprint(proxySSLPort),
|
||||
}
|
||||
return config.SetMany(appName, entries, false)
|
||||
}, map[string]string{"DOKKU_QUIET_OUTPUT": "1"})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(portMaps) == 0 {
|
||||
if len(rawTCPPorts) > 0 {
|
||||
for _, rawTcpPort := range rawTCPPorts {
|
||||
portMaps = append(portMaps, PortMap{
|
||||
ContainerPort: rawTcpPort,
|
||||
HostPort: rawTcpPort,
|
||||
Scheme: "http",
|
||||
})
|
||||
}
|
||||
} else {
|
||||
upstreamPort := 5000
|
||||
portFile := filepath.Join(common.AppRoot(appName), "PORT.web.1")
|
||||
if common.FileExists(portFile) {
|
||||
if port, err := strconv.Atoi(common.ReadFirstLine(portFile)); err == nil {
|
||||
upstreamPort = port
|
||||
}
|
||||
}
|
||||
|
||||
if dokkuProxyPort != 0 {
|
||||
portMaps = append(portMaps, PortMap{
|
||||
ContainerPort: upstreamPort,
|
||||
HostPort: dokkuProxyPort,
|
||||
Scheme: "http",
|
||||
})
|
||||
}
|
||||
if dokkuProxySSLPort != 0 {
|
||||
portMaps = append(portMaps, PortMap{
|
||||
ContainerPort: upstreamPort,
|
||||
HostPort: dokkuProxySSLPort,
|
||||
Scheme: "https",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if len(portMaps) > 0 {
|
||||
return setPortMaps(appName, portMaps)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TriggerRawTCPPorts extracts raw tcp port numbers from DOCKERFILE_PORTS config variable
|
||||
func TriggerPortsDockerfileRawTCPPorts(appName string) error {
|
||||
ports := getDockerfileRawTCPPorts(appName)
|
||||
|
||||
@@ -30,7 +30,7 @@ trigger-traefik-vhosts-docker-args-process-deploy() {
|
||||
fi
|
||||
|
||||
# ensure we have a port mapping
|
||||
plugn trigger proxy-configure-ports "$APP"
|
||||
plugn trigger ports-configure "$APP"
|
||||
|
||||
# gather port mapping information
|
||||
# we only support proxying a single port for http and https listeners
|
||||
|
||||
Reference in New Issue
Block a user