mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-20 04:42:33 +02:00
152 lines
3.5 KiB
Go
152 lines
3.5 KiB
Go
package model
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
. "github.com/yusing/go-proxy/internal/common"
|
|
D "github.com/yusing/go-proxy/internal/docker"
|
|
F "github.com/yusing/go-proxy/internal/utils/functional"
|
|
)
|
|
|
|
type (
|
|
RawEntry struct {
|
|
// raw entry object before validation
|
|
// loaded from docker labels or yaml file
|
|
Alias string `yaml:"-" json:"-"`
|
|
Scheme string `yaml:"scheme" json:"scheme"`
|
|
Host string `yaml:"host" json:"host"`
|
|
Port string `yaml:"port" json:"port"`
|
|
NoTLSVerify bool `yaml:"no_tls_verify" json:"no_tls_verify"` // https proxy only
|
|
PathPatterns []string `yaml:"path_patterns" json:"path_patterns"` // http(s) proxy only
|
|
Middlewares D.NestedLabelMap `yaml:"middlewares" json:"middlewares"`
|
|
|
|
/* Docker only */
|
|
*D.ProxyProperties `yaml:"-" json:"proxy_properties"`
|
|
}
|
|
|
|
RawEntries = F.Map[string, *RawEntry]
|
|
)
|
|
|
|
var NewProxyEntries = F.NewMapOf[string, *RawEntry]
|
|
|
|
func (e *RawEntry) FillMissingFields() bool {
|
|
isDocker := e.ProxyProperties != nil
|
|
if !isDocker {
|
|
e.ProxyProperties = &D.ProxyProperties{}
|
|
}
|
|
|
|
lp, pp, extra := e.splitPorts()
|
|
|
|
if port, ok := ServiceNamePortMapTCP[e.ImageName]; ok {
|
|
if pp == "" {
|
|
pp = strconv.Itoa(port)
|
|
}
|
|
if e.Scheme == "" {
|
|
e.Scheme = "tcp"
|
|
}
|
|
} else if port, ok := ImageNamePortMap[e.ImageName]; ok {
|
|
if pp == "" {
|
|
pp = strconv.Itoa(port)
|
|
}
|
|
if e.Scheme == "" {
|
|
e.Scheme = "http"
|
|
}
|
|
} else if pp == "" && e.Scheme == "https" {
|
|
pp = "443"
|
|
} else if pp == "" {
|
|
if p, ok := F.FirstValueOf(e.PrivatePortMapping); ok {
|
|
pp = fmt.Sprint(p.PrivatePort)
|
|
} else {
|
|
pp = "80"
|
|
}
|
|
}
|
|
|
|
// replace private port with public port (if any)
|
|
if isDocker && e.NetworkMode != "host" {
|
|
if p, ok := e.PrivatePortMapping[pp]; ok {
|
|
pp = fmt.Sprint(p.PublicPort)
|
|
}
|
|
if _, ok := e.PublicPortMapping[pp]; !ok { // port is not exposed, but specified
|
|
// try to fallback to first public port
|
|
if p, ok := F.FirstValueOf(e.PublicPortMapping); ok {
|
|
pp = fmt.Sprint(p.PublicPort)
|
|
} else if e.Running {
|
|
// ignore only if it is NOT RUNNING
|
|
// because stopped containers
|
|
// will have empty port mapping got from docker
|
|
logrus.Debugf("ignored port %s for %s", pp, e.ContainerName)
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
|
|
if e.Scheme == "" && isDocker {
|
|
if p, ok := e.PublicPortMapping[pp]; ok && p.Type == "udp" {
|
|
e.Scheme = "udp"
|
|
}
|
|
}
|
|
|
|
if e.Scheme == "" {
|
|
if lp != "" {
|
|
e.Scheme = "tcp"
|
|
} else if strings.HasSuffix(pp, "443") {
|
|
e.Scheme = "https"
|
|
} else if _, ok := WellKnownHTTPPorts[pp]; ok {
|
|
e.Scheme = "http"
|
|
} else {
|
|
// assume its http
|
|
e.Scheme = "http"
|
|
}
|
|
}
|
|
|
|
if e.Host == "" {
|
|
e.Host = "localhost"
|
|
}
|
|
if e.IdleTimeout == "" {
|
|
e.IdleTimeout = IdleTimeoutDefault
|
|
}
|
|
if e.WakeTimeout == "" {
|
|
e.WakeTimeout = WakeTimeoutDefault
|
|
}
|
|
if e.StopTimeout == "" {
|
|
e.StopTimeout = StopTimeoutDefault
|
|
}
|
|
if e.StopMethod == "" {
|
|
e.StopMethod = StopMethodDefault
|
|
}
|
|
|
|
e.Port = joinPorts(lp, pp, extra)
|
|
|
|
return true
|
|
}
|
|
|
|
func (e *RawEntry) splitPorts() (lp string, pp string, extra string) {
|
|
portSplit := strings.Split(e.Port, ":")
|
|
if len(portSplit) == 1 {
|
|
pp = portSplit[0]
|
|
} else {
|
|
lp = portSplit[0]
|
|
pp = portSplit[1]
|
|
}
|
|
if len(portSplit) > 2 {
|
|
extra = strings.Join(portSplit[2:], ":")
|
|
}
|
|
return
|
|
}
|
|
|
|
func joinPorts(lp string, pp string, extra string) string {
|
|
s := make([]string, 0, 3)
|
|
if lp != "" {
|
|
s = append(s, lp)
|
|
}
|
|
if pp != "" {
|
|
s = append(s, pp)
|
|
}
|
|
if extra != "" {
|
|
s = append(s, extra)
|
|
}
|
|
return strings.Join(s, ":")
|
|
}
|