mirror of
https://github.com/psviderski/uncloud.git
synced 2026-08-26 19:13:34 +00:00
78 lines
2.0 KiB
Go
78 lines
2.0 KiB
Go
package caddyconfig
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// templateContext holds the data available to Caddyfile templates.
|
|
type templateContext struct {
|
|
// Name is the current service name.
|
|
Name string
|
|
// Upstreams maps service names to their container IPs.
|
|
Upstreams map[string][]string
|
|
}
|
|
|
|
// upstreamsTemplateFn returns a template function that generates a space separated string of upstreams for the service.
|
|
// It optionally accepts a service name and a port number: {{upstreams [service-name] [port]}}.
|
|
func upstreamsTemplateFn(tmplCtx templateContext) func(args ...any) (string, error) {
|
|
return func(args ...any) (string, error) {
|
|
var serviceName string
|
|
var port int
|
|
|
|
// Parse arguments.
|
|
switch len(args) {
|
|
case 0:
|
|
// Current service, default port.
|
|
serviceName = tmplCtx.Name
|
|
case 1:
|
|
// Either port (int) for current service or service name (string).
|
|
switch arg := args[0].(type) {
|
|
case int:
|
|
serviceName = tmplCtx.Name
|
|
port = arg
|
|
case string:
|
|
serviceName = arg
|
|
port = 0
|
|
default:
|
|
return "", fmt.Errorf("upstreams function: invalid argument type: %T", arg)
|
|
}
|
|
case 2:
|
|
// Service name and port.
|
|
name, ok := args[0].(string)
|
|
if !ok {
|
|
return "", fmt.Errorf("upstreams function: first argument must be service name (string)")
|
|
}
|
|
serviceName = name
|
|
|
|
p, ok := args[1].(int)
|
|
if !ok {
|
|
return "", fmt.Errorf("upstreams function: second argument must be port (int)")
|
|
}
|
|
port = p
|
|
default:
|
|
return "", fmt.Errorf("upstreams function: too many arguments; expected 0-2, got %d", len(args))
|
|
}
|
|
|
|
ips, ok := tmplCtx.Upstreams[serviceName]
|
|
if !ok || len(ips) == 0 {
|
|
// No upstreams available.
|
|
return "", nil
|
|
}
|
|
|
|
// Build the space separated upstreams string.
|
|
var upstreams []string
|
|
for _, ip := range ips {
|
|
if port > 0 {
|
|
upstreams = append(upstreams, net.JoinHostPort(ip, strconv.Itoa(port)))
|
|
} else {
|
|
upstreams = append(upstreams, ip)
|
|
}
|
|
}
|
|
|
|
return strings.Join(upstreams, " "), nil
|
|
}
|
|
}
|