combining server configuration items to a single structure

This commit is contained in:
hyung-hwan 2025-01-28 02:35:11 +09:00
parent 2655da937f
commit d3afe29d5a
3 changed files with 87 additions and 93 deletions

View File

@ -44,6 +44,7 @@ type ClientTLSConfig struct {
type BasicAuthConfig struct { type BasicAuthConfig struct {
Enabled bool `yaml:"enabled"` Enabled bool `yaml:"enabled"`
Realm string `yaml:"realm"`
Users []string `yaml:"users"` Users []string `yaml:"users"`
UserFile string `yaml:"user-file"` UserFile string `yaml:"user-file"`
} }

View File

@ -91,50 +91,52 @@ func (sh *signal_handler) WriteLog(id string, level hodu.LogLevel, fmt string, a
func server_main(ctl_addrs []string, rpc_addrs []string, pxy_addrs []string, wpx_addrs []string, cfg *ServerConfig) error { func server_main(ctl_addrs []string, rpc_addrs []string, pxy_addrs []string, wpx_addrs []string, cfg *ServerConfig) error {
var s *hodu.Server var s *hodu.Server
var ctltlscfg *tls.Config var config *hodu.ServerConfig
var rpctlscfg *tls.Config
var pxytlscfg *tls.Config
var wpxtlscfg *tls.Config
var ctl_prefix string
var logger *AppLogger var logger *AppLogger
var log_mask hodu.LogMask var log_mask hodu.LogMask
var logfile string var logfile string
var logfile_maxsize int64 var logfile_maxsize int64
var logfile_rotate int var logfile_rotate int
var max_rpc_conns int
var max_peers int
var xterm_html_file string var xterm_html_file string
var xterm_html string var xterm_html string
var err error var err error
log_mask = hodu.LOG_ALL log_mask = hodu.LOG_ALL
config = &hodu.ServerConfig{
CtlAddrs: ctl_addrs,
RpcAddrs: rpc_addrs,
PxyAddrs: pxy_addrs,
WpxAddrs: wpx_addrs,
}
if cfg != nil { if cfg != nil {
ctltlscfg, err = make_tls_server_config(&cfg.CTL.TLS) config.CtlTls, err = make_tls_server_config(&cfg.CTL.TLS)
if err != nil { return err } if err != nil { return err }
rpctlscfg, err = make_tls_server_config(&cfg.RPC.TLS) config.RpcTls, err = make_tls_server_config(&cfg.RPC.TLS)
if err != nil { return err } if err != nil { return err }
pxytlscfg, err = make_tls_server_config(&cfg.PXY.TLS) config.PxyTls, err = make_tls_server_config(&cfg.PXY.TLS)
if err != nil { return err } if err != nil { return err }
wpxtlscfg, err = make_tls_server_config(&cfg.WPX.TLS) config.WpxTls, err = make_tls_server_config(&cfg.WPX.TLS)
if err != nil { return err } if err != nil { return err }
if len(ctl_addrs) <= 0 { ctl_addrs = cfg.CTL.Service.Addrs } if len(config.CtlAddrs) <= 0 { config.CtlAddrs = cfg.CTL.Service.Addrs }
if len(rpc_addrs) <= 0 { rpc_addrs = cfg.RPC.Service.Addrs } if len(config.RpcAddrs) <= 0 { config.RpcAddrs = cfg.RPC.Service.Addrs }
if len(pxy_addrs) <= 0 { pxy_addrs = cfg.PXY.Service.Addrs } if len(config.PxyAddrs) <= 0 { config.PxyAddrs = cfg.PXY.Service.Addrs }
if len(wpx_addrs) <= 0 { wpx_addrs = cfg.WPX.Service.Addrs } if len(config.WpxAddrs) <= 0 { config.WpxAddrs = cfg.WPX.Service.Addrs }
config.CtlPrefix = cfg.CTL.Service.Prefix
config.RpcMaxConns = cfg.APP.MaxRpcConns
config.MaxPeers = cfg.APP.MaxPeers
xterm_html_file = cfg.APP.XtermHtmlFile
ctl_prefix = cfg.CTL.Service.Prefix
log_mask = log_strings_to_mask(cfg.APP.LogMask) log_mask = log_strings_to_mask(cfg.APP.LogMask)
logfile = cfg.APP.LogFile logfile = cfg.APP.LogFile
logfile_maxsize = cfg.APP.LogMaxSize logfile_maxsize = cfg.APP.LogMaxSize
logfile_rotate = cfg.APP.LogRotate logfile_rotate = cfg.APP.LogRotate
max_rpc_conns = cfg.APP.MaxRpcConns
max_peers = cfg.APP.MaxPeers
xterm_html_file = cfg.APP.XtermHtmlFile
} }
if len(rpc_addrs) <= 0 { if len(config.RpcAddrs) <= 0 {
return fmt.Errorf("no rpc service addresses specified") return fmt.Errorf("no rpc service addresses specified")
} }
@ -160,17 +162,7 @@ func server_main(ctl_addrs []string, rpc_addrs []string, pxy_addrs []string, wpx
context.Background(), context.Background(),
HODU_NAME, HODU_NAME,
logger, logger,
ctl_addrs, config)
rpc_addrs,
pxy_addrs,
wpx_addrs,
ctl_prefix,
ctltlscfg,
rpctlscfg,
pxytlscfg,
wpxtlscfg,
max_rpc_conns,
max_peers)
if err != nil { if err != nil {
return fmt.Errorf("failed to create new server - %s", err.Error()) return fmt.Errorf("failed to create new server - %s", err.Error())
} }

125
server.go
View File

@ -42,26 +42,42 @@ type ServerSvcPortMap = map[PortId]ConnRouteId
type ServerWpxResponseTransformer func(r *ServerRouteProxyInfo, resp *http.Response) io.Reader type ServerWpxResponseTransformer func(r *ServerRouteProxyInfo, resp *http.Response) io.Reader
type ServerWpxForeignPortProxyMaker func(wpx_type string, port_id string) (*ServerRouteProxyInfo, error) type ServerWpxForeignPortProxyMaker func(wpx_type string, port_id string) (*ServerRouteProxyInfo, error)
type ServerCTLConfig struct { type ServerBasicAuthUser struct {
prefix string Username string
addrs []string Password string
basic_auth struct { }
enabled bool
users []string type ServerBasicAuth struct {
} Enabled bool
tls *tls.Config Realm string
User []ServerBasicAuthUser
}
type ServerConfig struct {
RpcAddrs []string
RpcTls *tls.Config
RpcMaxConns int
MaxPeers int
CtlAddrs []string
CtlTls *tls.Config
CtlPrefix string
CtlBasicAuth ServerBasicAuth
PxyAddrs []string
PxyTls *tls.Config
WpxAddrs []string
WpxTls *tls.Config
} }
type Server struct { type Server struct {
UnimplementedHoduServer UnimplementedHoduServer
Named Named
cfg *ServerConfig
ctx context.Context ctx context.Context
ctx_cancel context.CancelFunc ctx_cancel context.CancelFunc
pxytlscfg *tls.Config
wpxtlscfg *tls.Config
ctltlscfg *tls.Config
rpctlscfg *tls.Config
wg sync.WaitGroup wg sync.WaitGroup
stop_req atomic.Bool stop_req atomic.Bool
@ -70,18 +86,14 @@ type Server struct {
ext_mtx sync.Mutex ext_mtx sync.Mutex
ext_svcs []Service ext_svcs []Service
pxy_addr []string
pxy_ws *server_proxy_ssh_ws pxy_ws *server_proxy_ssh_ws
pxy_mux *http.ServeMux pxy_mux *http.ServeMux
pxy []*http.Server // proxy server pxy []*http.Server // proxy server
wpx_addr []string
wpx_ws *server_proxy_ssh_ws wpx_ws *server_proxy_ssh_ws
wpx_mux *http.ServeMux wpx_mux *http.ServeMux
wpx []*http.Server // proxy server than handles http/https only wpx []*http.Server // proxy server than handles http/https only
ctl_addr []string
ctl_prefix string
ctl_mux *http.ServeMux ctl_mux *http.ServeMux
ctl []*http.Server // control server ctl []*http.Server // control server
@ -975,7 +987,7 @@ func (s *Server) wrap_http_handler(handler ServerHttpHandler) http.Handler {
}) })
} }
func NewServer(ctx context.Context, name string, logger Logger, ctl_addrs []string, rpc_addrs []string, pxy_addrs []string, wpx_addrs []string, ctl_prefix string, ctltlscfg *tls.Config, rpctlscfg *tls.Config, pxytlscfg *tls.Config, wpxtlscfg *tls.Config, rpc_max int, peer_max int) (*Server, error) { func NewServer(ctx context.Context, name string, logger Logger, cfg *ServerConfig) (*Server, error) {
var s Server var s Server
var l *net.TCPListener var l *net.TCPListener
var rpcaddr *net.TCPAddr var rpcaddr *net.TCPAddr
@ -986,7 +998,7 @@ func NewServer(ctx context.Context, name string, logger Logger, ctl_addrs []stri
var opts []grpc.ServerOption var opts []grpc.ServerOption
var err error var err error
if len(rpc_addrs) <= 0 { if len(cfg.RpcAddrs) <= 0 {
return nil, fmt.Errorf("no server addresses provided") return nil, fmt.Errorf("no server addresses provided")
} }
@ -995,7 +1007,7 @@ func NewServer(ctx context.Context, name string, logger Logger, ctl_addrs []stri
s.log = logger s.log = logger
/* create the specified number of listeners */ /* create the specified number of listeners */
s.rpc = make([]*net.TCPListener, 0) s.rpc = make([]*net.TCPListener, 0)
for _, addr = range rpc_addrs { for _, addr = range cfg.RpcAddrs {
var addr_class string var addr_class string
addr_class = TcpAddrStrClass(addr) addr_class = TcpAddrStrClass(addr)
@ -1008,13 +1020,10 @@ func NewServer(ctx context.Context, name string, logger Logger, ctl_addrs []stri
s.rpc = append(s.rpc, l) s.rpc = append(s.rpc, l)
} }
s.ctltlscfg = ctltlscfg s.cfg = cfg
s.rpctlscfg = rpctlscfg
s.pxytlscfg = pxytlscfg
s.wpxtlscfg = wpxtlscfg
s.ext_svcs = make([]Service, 0, 1) s.ext_svcs = make([]Service, 0, 1)
s.pts_limit = peer_max s.pts_limit = cfg.MaxPeers
s.cts_limit = rpc_max s.cts_limit = cfg.RpcMaxConns
s.cts_next_id = 1 s.cts_next_id = 1
s.cts_map = make(ServerConnMap) s.cts_map = make(ServerConnMap)
s.cts_map_by_addr = make(ServerConnMapByAddr) s.cts_map_by_addr = make(ServerConnMapByAddr)
@ -1031,7 +1040,7 @@ func NewServer(ctx context.Context, name string, logger Logger, ctl_addrs []stri
*/ */
opts = append(opts, grpc.StatsHandler(&ConnCatcher{server: &s})) opts = append(opts, grpc.StatsHandler(&ConnCatcher{server: &s}))
if s.rpctlscfg != nil { opts = append(opts, grpc.Creds(credentials.NewTLS(s.rpctlscfg))) } if s.cfg.RpcTls != nil { opts = append(opts, grpc.Creds(credentials.NewTLS(s.cfg.RpcTls))) }
//opts = append(opts, grpc.UnaryInterceptor(unaryInterceptor)) //opts = append(opts, grpc.UnaryInterceptor(unaryInterceptor))
//opts = append(opts, grpc.StreamInterceptor(streamInterceptor)) //opts = append(opts, grpc.StreamInterceptor(streamInterceptor))
s.rpc_svr = grpc.NewServer(opts...) s.rpc_svr = grpc.NewServer(opts...)
@ -1043,36 +1052,32 @@ func NewServer(ctx context.Context, name string, logger Logger, ctl_addrs []stri
// --------------------------------------------------------- // ---------------------------------------------------------
s.ctl_prefix = ctl_prefix
s.ctl_mux = http.NewServeMux() s.ctl_mux = http.NewServeMux()
s.ctl_mux.Handle(s.ctl_prefix + "/_ctl/server-conns", s.ctl_mux.Handle(s.cfg.CtlPrefix + "/_ctl/server-conns",
s.wrap_http_handler(&server_ctl_server_conns{server_ctl{s: &s, id: HS_ID_CTL}})) s.wrap_http_handler(&server_ctl_server_conns{server_ctl{s: &s, id: HS_ID_CTL}}))
s.ctl_mux.Handle(s.ctl_prefix + "/_ctl/server-conns/{conn_id}", s.ctl_mux.Handle(s.cfg.CtlPrefix + "/_ctl/server-conns/{conn_id}",
s.wrap_http_handler(&server_ctl_server_conns_id{server_ctl{s: &s, id: HS_ID_CTL}})) s.wrap_http_handler(&server_ctl_server_conns_id{server_ctl{s: &s, id: HS_ID_CTL}}))
s.ctl_mux.Handle(s.ctl_prefix + "/_ctl/server-conns/{conn_id}/routes", s.ctl_mux.Handle(s.cfg.CtlPrefix + "/_ctl/server-conns/{conn_id}/routes",
s.wrap_http_handler(&server_ctl_server_conns_id_routes{server_ctl{s: &s, id: HS_ID_CTL}})) s.wrap_http_handler(&server_ctl_server_conns_id_routes{server_ctl{s: &s, id: HS_ID_CTL}}))
s.ctl_mux.Handle(s.ctl_prefix + "/_ctl/server-conns/{conn_id}/routes/{route_id}", s.ctl_mux.Handle(s.cfg.CtlPrefix + "/_ctl/server-conns/{conn_id}/routes/{route_id}",
s.wrap_http_handler(&server_ctl_server_conns_id_routes_id{server_ctl{s: &s, id: HS_ID_CTL}})) s.wrap_http_handler(&server_ctl_server_conns_id_routes_id{server_ctl{s: &s, id: HS_ID_CTL}}))
s.ctl_mux.Handle(s.ctl_prefix + "/_ctl/stats", s.ctl_mux.Handle(s.cfg.CtlPrefix + "/_ctl/stats",
s.wrap_http_handler(&server_ctl_stats{server_ctl{s: &s, id: HS_ID_CTL}})) s.wrap_http_handler(&server_ctl_stats{server_ctl{s: &s, id: HS_ID_CTL}}))
// TODO: make this optional. add this endpoint only if it's enabled... // TODO: make this optional. add this endpoint only if it's enabled...
s.promreg = prometheus.NewRegistry() s.promreg = prometheus.NewRegistry()
s.promreg.MustRegister(prometheus.NewGoCollector()) s.promreg.MustRegister(prometheus.NewGoCollector())
s.promreg.MustRegister(NewServerCollector(&s)) s.promreg.MustRegister(NewServerCollector(&s))
s.ctl_mux.Handle(s.ctl_prefix + "/_ctl/metrics", s.ctl_mux.Handle(s.cfg.CtlPrefix + "/_ctl/metrics",
promhttp.HandlerFor(s.promreg, promhttp.HandlerOpts{ EnableOpenMetrics: true })) promhttp.HandlerFor(s.promreg, promhttp.HandlerOpts{ EnableOpenMetrics: true }))
s.ctl_addr = make([]string, len(ctl_addrs)) s.ctl = make([]*http.Server, len(cfg.CtlAddrs))
s.ctl = make([]*http.Server, len(ctl_addrs)) for i = 0; i < len(cfg.CtlAddrs); i++ {
copy(s.ctl_addr, ctl_addrs)
for i = 0; i < len(ctl_addrs); i++ {
s.ctl[i] = &http.Server{ s.ctl[i] = &http.Server{
Addr: ctl_addrs[i], Addr: cfg.CtlAddrs[i],
Handler: s.ctl_mux, Handler: s.ctl_mux,
TLSConfig: s.ctltlscfg, TLSConfig: s.cfg.CtlTls,
ErrorLog: hs_log, ErrorLog: hs_log,
// TODO: more settings // TODO: more settings
} }
@ -1104,15 +1109,13 @@ func NewServer(ctx context.Context, name string, logger Logger, ctl_addrs []stri
s.pxy_mux.Handle("/_http/{conn_id}/{route_id}/{trailer...}", s.pxy_mux.Handle("/_http/{conn_id}/{route_id}/{trailer...}",
s.wrap_http_handler(&server_proxy_http_main{server_proxy: server_proxy{s: &s, id: HS_ID_PXY}, prefix: "/_http"})) s.wrap_http_handler(&server_proxy_http_main{server_proxy: server_proxy{s: &s, id: HS_ID_PXY}, prefix: "/_http"}))
s.pxy_addr = make([]string, len(pxy_addrs)) s.pxy = make([]*http.Server, len(cfg.PxyAddrs))
s.pxy = make([]*http.Server, len(pxy_addrs))
copy(s.pxy_addr, pxy_addrs)
for i = 0; i < len(pxy_addrs); i++ { for i = 0; i < len(cfg.PxyAddrs); i++ {
s.pxy[i] = &http.Server{ s.pxy[i] = &http.Server{
Addr: pxy_addrs[i], Addr: cfg.PxyAddrs[i],
Handler: s.pxy_mux, Handler: s.pxy_mux,
TLSConfig: s.pxytlscfg, TLSConfig: cfg.PxyTls,
ErrorLog: hs_log, ErrorLog: hs_log,
// TODO: more settings // TODO: more settings
} }
@ -1145,15 +1148,13 @@ func NewServer(ctx context.Context, name string, logger Logger, ctl_addrs []stri
s.wpx_mux.Handle("/", s.wpx_mux.Handle("/",
s.wrap_http_handler(&server_proxy_http_wpx{server_proxy: server_proxy{s: &s, id: HS_ID_WPX}})) s.wrap_http_handler(&server_proxy_http_wpx{server_proxy: server_proxy{s: &s, id: HS_ID_WPX}}))
s.wpx_addr = make([]string, len(wpx_addrs)) s.wpx = make([]*http.Server, len(cfg.WpxAddrs))
s.wpx = make([]*http.Server, len(wpx_addrs))
copy(s.wpx_addr, wpx_addrs)
for i = 0; i < len(wpx_addrs); i++ { for i = 0; i < len(cfg.WpxAddrs); i++ {
s.wpx[i] = &http.Server{ s.wpx[i] = &http.Server{
Addr: wpx_addrs[i], Addr: cfg.WpxAddrs[i],
Handler: s.wpx_mux, Handler: s.wpx_mux,
TLSConfig: s.wpxtlscfg, TLSConfig: cfg.WpxTls,
ErrorLog: hs_log, ErrorLog: hs_log,
} }
} }
@ -1266,7 +1267,7 @@ func (s *Server) RunCtlTask(wg *sync.WaitGroup) {
go func(i int, cs *http.Server) { go func(i int, cs *http.Server) {
var l net.Listener var l net.Listener
s.log.Write("", LOG_INFO, "Control channel[%d] started on %s", i, s.ctl_addr[i]) s.log.Write("", LOG_INFO, "Control channel[%d] started on %s", i, s.cfg.CtlAddrs[i])
if s.stop_req.Load() == false { if s.stop_req.Load() == false {
// defeat hard-coded "tcp" in ListenAndServe() and ListenAndServeTLS() // defeat hard-coded "tcp" in ListenAndServe() and ListenAndServeTLS()
@ -1275,10 +1276,10 @@ func (s *Server) RunCtlTask(wg *sync.WaitGroup) {
l, err = net.Listen(TcpAddrStrClass(cs.Addr), cs.Addr) l, err = net.Listen(TcpAddrStrClass(cs.Addr), cs.Addr)
if err == nil { if err == nil {
if s.stop_req.Load() == false { if s.stop_req.Load() == false {
if s.ctltlscfg == nil { if s.cfg.CtlTls == nil {
err = cs.Serve(l) err = cs.Serve(l)
} else { } else {
err = cs.ServeTLS(l, "", "") // s.ctltlscfg must provide a certificate and a key err = cs.ServeTLS(l, "", "") // s.cfg.CtlTls must provide a certificate and a key
} }
} else { } else {
err = fmt.Errorf("stop requested") err = fmt.Errorf("stop requested")
@ -1312,16 +1313,16 @@ func (s *Server) RunPxyTask(wg *sync.WaitGroup) {
go func(i int, cs *http.Server) { go func(i int, cs *http.Server) {
var l net.Listener var l net.Listener
s.log.Write("", LOG_INFO, "Proxy channel[%d] started on %s", i, s.pxy_addr[i]) s.log.Write("", LOG_INFO, "Proxy channel[%d] started on %s", i, s.cfg.PxyAddrs[i])
if s.stop_req.Load() == false { if s.stop_req.Load() == false {
l, err = net.Listen(TcpAddrStrClass(cs.Addr), cs.Addr) l, err = net.Listen(TcpAddrStrClass(cs.Addr), cs.Addr)
if err == nil { if err == nil {
if s.stop_req.Load() == false { if s.stop_req.Load() == false {
if s.pxytlscfg == nil { // TODO: change this if s.cfg.PxyTls == nil { // TODO: change this
err = cs.Serve(l) err = cs.Serve(l)
} else { } else {
err = cs.ServeTLS(l, "", "") // s.pxytlscfg must provide a certificate and a key err = cs.ServeTLS(l, "", "") // s.cfg.PxyTls must provide a certificate and a key
} }
} else { } else {
err = fmt.Errorf("stop requested") err = fmt.Errorf("stop requested")
@ -1355,16 +1356,16 @@ func (s *Server) RunWpxTask(wg *sync.WaitGroup) {
go func(i int, cs *http.Server) { go func(i int, cs *http.Server) {
var l net.Listener var l net.Listener
s.log.Write("", LOG_INFO, "Wpx channel[%d] started on %s", i, s.wpx_addr[i]) s.log.Write("", LOG_INFO, "Wpx channel[%d] started on %s", i, s.cfg.WpxAddrs[i])
if s.stop_req.Load() == false { if s.stop_req.Load() == false {
l, err = net.Listen(TcpAddrStrClass(cs.Addr), cs.Addr) l, err = net.Listen(TcpAddrStrClass(cs.Addr), cs.Addr)
if err == nil { if err == nil {
if s.stop_req.Load() == false { if s.stop_req.Load() == false {
if s.wpxtlscfg == nil { // TODO: change this if s.cfg.WpxTls == nil { // TODO: change this
err = cs.Serve(l) err = cs.Serve(l)
} else { } else {
err = cs.ServeTLS(l, "", "") // s.wpxtlscfg must provide a certificate and a key err = cs.ServeTLS(l, "", "") // s.cfg.WpxTls must provide a certificate and a key
} }
} else { } else {
err = fmt.Errorf("stop requested") err = fmt.Errorf("stop requested")
@ -1679,7 +1680,7 @@ func (s *Server) WriteLog(id string, level LogLevel, fmtstr string, args ...inte
} }
func (s *Server) AddCtlHandler(path string, handler ServerHttpHandler) { func (s *Server) AddCtlHandler(path string, handler ServerHttpHandler) {
s.ctl_mux.Handle(s.ctl_prefix + "/_ctl" + path, s.wrap_http_handler(handler)) s.ctl_mux.Handle(s.cfg.CtlPrefix + "/_ctl" + path, s.wrap_http_handler(handler))
} }
func (s *Server) AddCtlMetricsCollector(col prometheus.Collector) error { func (s *Server) AddCtlMetricsCollector(col prometheus.Collector) error {