Files
dokku/plugins/ports/triggers.go
Jose Diaz-Gonzalez 129691eb6e fix: ensure we continue on with logic if the error returned from fetching all apps is NoAppsExist
This makes it so we don't accidentally skip logic that happens after iterate over the apps.
2025-12-05 20:16:15 -05:00

264 lines
6.1 KiB
Go

package ports
import (
"encoding/json"
"errors"
"fmt"
"sort"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/config"
)
// TriggerInstall migrates the ports config to properties
func TriggerInstall() error {
if err := common.PropertySetup("ports"); err != nil {
return fmt.Errorf("Unable to install the ports plugin: %s", err.Error())
}
apps, err := common.UnfilteredDokkuApps()
if err != nil && !errors.Is(err, common.NoAppsExist) {
return nil
}
for _, appName := range apps {
if common.PropertyExists("ports", appName, "map") {
continue
}
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get",
Args: []string{appName, "DOKKU_PROXY_PORT_MAP"},
})
portMapString := results.StdoutContents()
if portMapString == "" {
continue
}
common.LogVerboseQuiet(fmt.Sprintf("Setting %s ports property 'map' to %v", appName, portMapString))
portMaps, _ := parsePortMapString(portMapString)
propertyValue := []string{}
for _, portMap := range portMaps {
propertyValue = append(propertyValue, portMap.String())
}
if err := common.PropertyListWrite("ports", appName, "map", propertyValue); err != nil {
return err
}
_, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-unset",
Args: []string{appName, "DOKKU_PROXY_PORT_MAP"},
})
if err != nil {
return err
}
}
return nil
}
// TriggerPortsClear removes all ports for the specified app
func TriggerPortsClear(appName string) error {
return clearPorts(appName)
}
// TriggerPortsConfigure ensures we have a port mapping
func TriggerPortsConfigure(appName string) error {
if err := initializeProxyPort(appName); err != nil {
return err
}
if err := initializeProxySSLPort(appName); err != nil {
return err
}
return nil
}
// TriggerPortsGet prints out the port mapping for a given app
func TriggerPortsGet(appName string, format string) error {
if format == "" {
format = "stdout"
}
if format != "json" && format != "stdout" {
return fmt.Errorf("Invalid format specified: %s", format)
}
portMaps := getPortMaps(appName)
if len(portMaps) == 0 {
portMaps = getDetectedPortMaps(appName)
}
persisted := []PortMap{}
for _, portMap := range portMaps {
if portMap.AllowsPersistence() {
continue
}
persisted = append(persisted, portMap)
}
persisted = uniquePortMaps(persisted)
if format == "json" {
b, err := json.Marshal(persisted)
if err != nil {
return fmt.Errorf("Unable to marshal port mapping: %s", err.Error())
}
fmt.Println(string(b))
return nil
}
for _, portMap := range persisted {
fmt.Println(portMap)
}
return nil
}
// TriggerPortsGetAvailable prints out an available port greater than 1024
func TriggerPortsGetAvailable() error {
port := getAvailablePort()
if port > 0 {
common.Log(fmt.Sprint(port))
}
return nil
}
// TriggerPortsGetProperty writes the ports key to stdout for a given app container
func TriggerPortsGetProperty(appName string, key string) error {
if key == "proxy-port" {
fmt.Println(getComputedProxyPort(appName))
return nil
}
if key == "proxy-ssl-port" {
fmt.Println(getComputedProxySSLPort(appName))
return nil
}
fmt.Println(common.PropertyGet("ports", appName, key))
return nil
}
// TriggerPortsSetDetected writes out detected ports
func TriggerPortsSetDetected(appName string, portMapString string) error {
portMaps, _ := parsePortMapString(portMapString)
var value []string
for _, portMap := range uniquePortMaps(portMaps) {
if portMap.AllowsPersistence() {
continue
}
value = append(value, portMap.String())
}
sort.Strings(value)
return common.PropertyListWrite("ports", appName, "map-detected", value)
}
// TriggerPostAppCloneSetup creates new ports files
func TriggerPostAppCloneSetup(oldAppName string, newAppName string) error {
err := common.PropertyClone("ports", oldAppName, newAppName)
if err != nil {
return err
}
return nil
}
// TriggerPostAppRenameSetup renames ports files
func TriggerPostAppRenameSetup(oldAppName string, newAppName string) error {
if err := common.PropertyClone("ports", oldAppName, newAppName); err != nil {
return err
}
if err := common.PropertyDestroy("ports", oldAppName); err != nil {
return err
}
return nil
}
// TriggerPostCertsRemove unsets port config vars after SSL cert is added
func TriggerPostCertsRemove(appName string) error {
keys := []string{"DOKKU_PROXY_SSL_PORT"}
if err := config.UnsetMany(appName, keys, false); err != nil {
return err
}
return removePortMaps(appName, filterAppPortMaps(appName, "https", 443))
}
// TriggerPostCertsUpdate sets port config vars after SSL cert is added
func TriggerPostCertsUpdate(appName string) error {
port := config.GetWithDefault(appName, "DOKKU_PROXY_PORT", "")
sslPort := config.GetWithDefault(appName, "DOKKU_PROXY_SSL_PORT", "")
portMaps := getPortMaps(appName)
toUnset := []string{}
if port == "80" {
toUnset = append(toUnset, "DOKKU_PROXY_PORT")
}
if sslPort == "443" {
toUnset = append(toUnset, "DOKKU_PROXY_SSL_PORT")
}
if len(toUnset) > 0 {
if err := config.UnsetMany(appName, toUnset, false); err != nil {
return err
}
}
var http80Ports []PortMap
for _, portMap := range portMaps {
if portMap.Scheme == "http" && portMap.HostPort == 80 {
http80Ports = append(http80Ports, portMap)
}
}
http80Ports = uniquePortMaps(http80Ports)
if len(http80Ports) > 0 {
var https443Ports []PortMap
for _, portMap := range portMaps {
if portMap.Scheme == "https" && portMap.HostPort == 443 {
https443Ports = append(https443Ports, portMap)
}
}
if err := removePortMaps(appName, https443Ports); err != nil {
return err
}
var toAdd []PortMap
for _, portMap := range http80Ports {
toAdd = append(toAdd, PortMap{
Scheme: "https",
HostPort: 443,
ContainerPort: portMap.ContainerPort,
})
}
if err := addPortMaps(appName, toAdd); err != nil {
return err
}
}
return nil
}
// TriggerPostDelete is the ports post-delete plugin trigger
func TriggerPostDelete(appName string) error {
if err := common.PropertyDestroy("ports", appName); err != nil {
common.LogWarn(err.Error())
}
return nil
}