You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
3.4 KiB
114 lines
3.4 KiB
// tera-accessd owns the target's dynamically configured management listeners.
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"log"
|
|
"net"
|
|
"os"
|
|
"os/signal"
|
|
"path/filepath"
|
|
"strings"
|
|
"syscall"
|
|
|
|
"tera-clone/services/tera-api/internal/managementaccess"
|
|
"tera-clone/services/tera-api/internal/webgateway"
|
|
)
|
|
|
|
func main() {
|
|
socketPath := accessGetenv("TERA_ACCESSD_SOCKET", managementaccess.DefaultSocketPath)
|
|
handler, err := webgateway.NewHandler(webgateway.Options{
|
|
StaticRoot: accessGetenv("TERA_ACCESSD_STATIC_ROOT", "/usr/share/tera-web"),
|
|
APIUpstream: accessGetenv("TERA_ACCESSD_API_UPSTREAM", "http://127.0.0.1:8082"),
|
|
SessionUpstream: accessGetenv("TERA_ACCESSD_SESSION_UPSTREAM", "http://127.0.0.1:8081"),
|
|
})
|
|
if err != nil {
|
|
log.Fatalf("tera-accessd web setup failed: %v", err)
|
|
}
|
|
runtime, err := managementaccess.NewRuntime(managementaccess.RuntimeOptions{
|
|
BindHost: accessGetenv("TERA_ACCESSD_BIND_HOST", "0.0.0.0"),
|
|
Handler: handler,
|
|
CertFile: accessGetenv("TERA_ACCESSD_TLS_CERT", "/var/lib/tera-accessd/tls/server.crt"),
|
|
KeyFile: accessGetenv("TERA_ACCESSD_TLS_KEY", "/var/lib/tera-accessd/tls/server.key"),
|
|
TLSHosts: accessGetenvList("TERA_ACCESSD_TLS_HOSTS", []string{"192.168.0.223", "localhost", "127.0.0.1"}),
|
|
})
|
|
if err != nil {
|
|
log.Fatalf("tera-accessd runtime setup failed: %v", err)
|
|
}
|
|
defer runtime.Close()
|
|
listener, err := listenControlSocket(socketPath)
|
|
if err != nil {
|
|
log.Fatalf("tera-accessd control socket setup failed: %v", err)
|
|
}
|
|
defer func() {
|
|
_ = listener.Close()
|
|
_ = os.Remove(socketPath)
|
|
}()
|
|
server := managementaccess.SocketServer{Controller: runtime}
|
|
errorsChannel := make(chan error, 1)
|
|
go func() { errorsChannel <- server.Serve(listener) }()
|
|
log.Printf("tera-accessd serving management access control on %s", socketPath)
|
|
signalContext, stopSignals := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
|
defer stopSignals()
|
|
select {
|
|
case <-signalContext.Done():
|
|
_ = listener.Close()
|
|
if err := <-errorsChannel; err != nil {
|
|
log.Printf("tera-accessd control shutdown failed: %v", err)
|
|
}
|
|
case err := <-errorsChannel:
|
|
if err != nil {
|
|
log.Fatalf("tera-accessd control service failed: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func listenControlSocket(socketPath string) (net.Listener, error) {
|
|
if socketPath == "" || !filepath.IsAbs(socketPath) {
|
|
return nil, errors.New("TERA_ACCESSD_SOCKET must be an absolute path")
|
|
}
|
|
if err := os.MkdirAll(filepath.Dir(socketPath), 0o750); err != nil {
|
|
return nil, err
|
|
}
|
|
if info, err := os.Lstat(socketPath); err == nil {
|
|
if info.Mode()&os.ModeSocket == 0 {
|
|
return nil, errors.New("refusing to replace non-socket management access path")
|
|
}
|
|
if err := os.Remove(socketPath); err != nil {
|
|
return nil, err
|
|
}
|
|
} else if !os.IsNotExist(err) {
|
|
return nil, err
|
|
}
|
|
listener, err := net.Listen("unix", socketPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if err := os.Chmod(socketPath, 0o660); err != nil {
|
|
_ = listener.Close()
|
|
return nil, err
|
|
}
|
|
return listener, nil
|
|
}
|
|
|
|
func accessGetenv(key, fallback string) string {
|
|
if value := strings.TrimSpace(os.Getenv(key)); value != "" {
|
|
return value
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func accessGetenvList(key string, fallback []string) []string {
|
|
value := strings.TrimSpace(os.Getenv(key))
|
|
if value == "" {
|
|
return fallback
|
|
}
|
|
result := make([]string, 0)
|
|
for _, item := range strings.Split(value, ",") {
|
|
if item = strings.TrimSpace(item); item != "" {
|
|
result = append(result, item)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|