proxy-pool/cmd/proxy-gateway/main.go

119 lines
4.0 KiB
Go

package main
import (
"context"
"errors"
"flag"
"fmt"
"io"
"os"
"os/signal"
"strconv"
"strings"
"syscall"
"proxy-pool/internal/config"
"proxy-pool/internal/gateway/bootstrap"
"proxy-pool/internal/platform/logging"
)
const (
configEnvironment = "PROXY_POOL_CONFIG"
controlPlaneAddressEnvironment = "PROXY_POOL_CONTROL_PLANE_ADDRESS"
clusterIDEnvironment = "PROXY_POOL_CLUSTER_ID"
workerIDEnvironment = "PROXY_POOL_WORKER_ID"
instanceIDEnvironment = "PROXY_POOL_INSTANCE_ID"
autoIdentityEnvironment = "PROXY_POOL_AUTO_IDENTITY"
zoneEnvironment = "PROXY_POOL_ZONE"
)
type environmentLookup func(string) string
type gatewayRun func(context.Context, bootstrap.Options) error
func main() {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
os.Exit(execute(ctx, os.Args[1:], os.Getenv, bootstrap.Run, os.Stderr))
}
func execute(
ctx context.Context,
args []string,
getenv environmentLookup,
run gatewayRun,
stderr io.Writer,
) int {
flags := flag.NewFlagSet("proxy-gateway", flag.ContinueOnError)
flags.SetOutput(stderr)
configPath := flags.String("config", "", "configuration file path")
controlPlaneAddress := flags.String("control-plane", "", "remote Controller control-plane address")
clusterID := flags.String("cluster-id", "", "cluster identifier")
workerID := flags.String("worker-id", "", "unique Worker identifier")
instanceID := flags.String("instance-id", "", "unique process instance identifier")
autoIdentity := flags.Bool("auto-identity", false, "derive Worker and missing instance IDs from the mTLS SPIFFE certificate")
zone := flags.String("zone", "", "availability zone identifier")
if err := flags.Parse(args); err != nil {
if errors.Is(err, flag.ErrHelp) {
return 0
}
return 2
}
if flags.NArg() != 0 {
_, _ = fmt.Fprintln(stderr, "proxy-gateway: unexpected positional arguments")
return 2
}
if getenv != nil {
setIfEmpty(configPath, getenv(configEnvironment))
setIfEmpty(controlPlaneAddress, getenv(controlPlaneAddressEnvironment))
setIfEmpty(clusterID, getenv(clusterIDEnvironment))
setIfEmpty(workerID, getenv(workerIDEnvironment))
setIfEmpty(instanceID, getenv(instanceIDEnvironment))
setIfEmpty(zone, getenv(zoneEnvironment))
if !flagWasSet(flags, "auto-identity") {
if value, err := strconv.ParseBool(getenv(autoIdentityEnvironment)); err == nil {
*autoIdentity = value
}
}
}
missingIdentity := !*autoIdentity && (!validValue(*workerID) || !validValue(*instanceID))
invalidProvidedIdentity := (*workerID != "" && !validValue(*workerID)) || (*instanceID != "" && !validValue(*instanceID))
if ctx == nil || run == nil || !validValue(*configPath) || !validValue(*controlPlaneAddress) ||
!validValue(*clusterID) || missingIdentity || invalidProvidedIdentity || !validValue(*zone) {
_, _ = fmt.Fprintf(stderr,
"proxy-gateway: -config, -control-plane, -cluster-id and -zone are required; -worker-id/-instance-id are required unless -auto-identity is enabled; "+
"environment fallbacks: %s, %s, %s, %s, %s, %s, %s\n",
configEnvironment, controlPlaneAddressEnvironment, clusterIDEnvironment, workerIDEnvironment, instanceIDEnvironment, zoneEnvironment, autoIdentityEnvironment,
)
return 2
}
err := run(ctx, bootstrap.Options{
ConfigPath: *configPath, Resolver: config.OSResolver{}, ControlPlaneAddress: *controlPlaneAddress,
ClusterID: *clusterID, WorkerID: *workerID, InstanceID: *instanceID, AutoIdentity: *autoIdentity, Zone: *zone,
})
if err == nil || (errors.Is(err, context.Canceled) && ctx.Err() != nil) {
return 0
}
logging.WriteProcessError(stderr, "proxy-gateway", err)
return 1
}
func flagWasSet(flags *flag.FlagSet, name string) bool {
set := false
flags.Visit(func(item *flag.Flag) {
if item.Name == name {
set = true
}
})
return set
}
func setIfEmpty(target *string, value string) {
if target != nil && *target == "" {
*target = value
}
}
func validValue(value string) bool {
return value != "" && strings.TrimSpace(value) == value
}