Skip to content

Commit

Permalink
feature: add basic dashboard
Browse files Browse the repository at this point in the history
  • Loading branch information
almeidapaulopt committed Oct 31, 2024
1 parent 25ee960 commit 278d55f
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 38 deletions.
19 changes: 19 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ dev: docker_start server_start
server_start:
TSDPROXY_DataDir=./dev/data TSDPROXY_LOG_LEVEL=debug DOCKER_HOST=unix:///var/run/docker.sock \
TSDPROXY_AUTHKEYFILE=./dev/KEY_FILE \
TSDPROXY_DASHBOARD_ENABLED=true \
TSDPROXY_DASHBOARD_NAME=DASH1 \
wgo run -file=.go -file=.yaml -file=.env -file=.json -file=.toml ${MAIN_PACKAGE_PATH}

## docker_start: start the docker containers
Expand All @@ -117,6 +119,23 @@ docker_stop:
.PHONY: stop
stop: dev_kill docker_stop

## docker_image: Create docker image
.PHONY: docker_image
docker_image:
docker buildx build -t "tsdproxy:latest" .

## docker_local image start
.PHONY: docker_image_start
docker_image_start:
docker compose -f dev/docker-compose.yaml up -d

## docker_local image stop
.PHONY: docker_image_stop
docker_image_stop:
docker compose -f dev/docker-compose.yaml down



# ==================================================================================== #
# QUALITY CONTROL
# ==================================================================================== #
Expand Down
11 changes: 11 additions & 0 deletions cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/docker/docker/client"

"github.com/almeidapaulopt/tsdproxy/internal/core"
"github.com/almeidapaulopt/tsdproxy/internal/dashboard"
pm "github.com/almeidapaulopt/tsdproxy/internal/proxymanager"
)

Expand All @@ -25,6 +26,7 @@ type WebApp struct {
Health *core.Health
Docker *client.Client
ProxyManager *pm.ProxyManager
Dashboard *dashboard.Dashboard
}

func InitializeApp() (*WebApp, error) {
Expand All @@ -47,13 +49,18 @@ func InitializeApp() (*WebApp, error) {
//
proxymanager := pm.NewProxyManager(docker, logger, config)

// init Dashboard
//
dash := dashboard.NewDashboard(httpServer, logger, config, proxymanager.Proxies)

webApp := &WebApp{
Config: config,
Log: logger,
HTTP: httpServer,
Health: health,
Docker: docker,
ProxyManager: proxymanager,
Dashboard: dash,
}
return webApp, nil
}
Expand Down Expand Up @@ -95,6 +102,10 @@ func (app *WebApp) Start() {
//
go app.ProxyManager.WatchDockerEvents(ctx)

// Start Dashboard
//
app.Dashboard.AddRoutes()

// Start the webserver
//
go func() {
Expand Down
43 changes: 43 additions & 0 deletions internal/dashboard/dash.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package dashboard

import (
"net/http"

"github.com/almeidapaulopt/tsdproxy/internal/core"
"github.com/almeidapaulopt/tsdproxy/internal/proxymanager"
)

type Dashboard struct {
Log *core.Logger
HTTP *core.HTTPServer
Config *core.Config
proxies proxymanager.ProxyList
}

func NewDashboard(http *core.HTTPServer, log *core.Logger, cfg *core.Config, pl proxymanager.ProxyList) *Dashboard {
return &Dashboard{
Log: log,
HTTP: http,
Config: cfg,
proxies: pl,
}
}

func (dash *Dashboard) AddRoutes() {
dash.HTTP.Handle("GET /", dash.index())
}

func (dash *Dashboard) index() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>`))
for _, p := range dash.proxies {
w.Write([]byte(p.URL.String() + "\n"))
}
w.Write([]byte(`</body></html>`))
}
}
21 changes: 11 additions & 10 deletions internal/proxymanager/proxymanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ import (
"github.com/almeidapaulopt/tsdproxy/internal/tailscale"
)

type ProxyList map[string]*Proxy

type ProxyManager struct {
proxies map[string]*Proxy
Proxies ProxyList
docker *client.Client
Log *core.Logger
config *core.Config
Expand All @@ -39,7 +41,7 @@ type Proxy struct {

func NewProxyManager(cli *client.Client, logger *core.Logger, config *core.Config) *ProxyManager {
return &ProxyManager{
proxies: make(map[string]*Proxy),
Proxies: make(ProxyList),
docker: cli,
config: config,
Log: logger,
Expand All @@ -50,21 +52,21 @@ func (pm *ProxyManager) AddProxy(proxy *Proxy) {
pm.mutex.Lock()
defer pm.mutex.Unlock()

pm.proxies[proxy.container.ID] = proxy
pm.Proxies[proxy.container.ID] = proxy
}

func (pm *ProxyManager) RemoveProxy(containerID string) {
pm.mutex.Lock()
defer pm.mutex.Unlock()

if proxy, exists := pm.proxies[containerID]; exists {
if proxy, exists := pm.Proxies[containerID]; exists {
if err := proxy.TsServer.Close(); err != nil {
pm.Log.Error().Err(err).Str("containerID", containerID).Msg("Error shutting down proxy server")
} else {
pm.Log.Info().Str("containerID", containerID).Msg("Proxy server shut down successfully")
}

delete(pm.proxies, containerID)
delete(pm.Proxies, containerID)
pm.Log.Info().Str("containerID", containerID[:12]).Msg("Removed proxy for container")
}
}
Expand Down Expand Up @@ -146,13 +148,12 @@ func (pm *ProxyManager) SetupProxy(ctx context.Context, containerID string) {

// Create the tsnet server
//
server := tailscale.NewTsNetServer(proxyURL.Hostname(), pm.config, pm.Log)
defer server.Close()

if err := server.Start(ctx); err != nil {
server, err := tailscale.NewTsNetServer(proxyURL.Hostname(), pm.config, pm.Log)
if err != nil {
pm.Log.Error().Err(err).Str("containerID", containerID).Str("containerName", container.GetName()).Msg("Error starting server")
return
}
defer server.Close()

// Create the TLS listener
//
Expand Down Expand Up @@ -223,7 +224,7 @@ func (pm *ProxyManager) WatchDockerEvents(ctx context.Context) {

func (pm *ProxyManager) StopAll() {
pm.Log.Info().Msg("Shutdown all proxies")
for id := range pm.proxies {
for id := range pm.Proxies {
pm.RemoveProxy(id)
}
}
Expand Down
53 changes: 25 additions & 28 deletions internal/tailscale/tailscale.go
Original file line number Diff line number Diff line change
@@ -1,48 +1,45 @@
package tailscale

import (
"context"
"fmt"
"path/filepath"

"github.com/almeidapaulopt/tsdproxy/internal/core"
tsclient "tailscale.com/client/tailscale"
"tailscale.com/tsnet"
)

type TsNetServer struct {
TsServer *tsnet.Server
TsServer *tsnet.Server
LocalClient *tsclient.LocalClient
}

func NewTsNetServer(hostname string, config *core.Config, logger *core.Logger) *TsNetServer {
return &TsNetServer{
&tsnet.Server{
Hostname: hostname,
AuthKey: config.AuthKey,
Dir: filepath.Join(config.DataDir, hostname),
Ephemeral: true,
Logf: func(format string, args ...any) {
logger.Trace().Msgf(format, args...)
},
UserLogf: func(format string, args ...any) {
logger.Trace().Msgf(format, args...)
},
func NewTsNetServer(hostname string, config *core.Config, logger *core.Logger) (*TsNetServer, error) {
tserver := &tsnet.Server{
Hostname: hostname,
AuthKey: config.AuthKey,
Dir: filepath.Join(config.DataDir, hostname),
Ephemeral: true,
RunWebClient: true,
Logf: func(format string, args ...any) {
logger.Trace().Msgf(format, args...)
},
UserLogf: func(format string, args ...any) {
logger.Trace().Msgf(format, args...)
},
}
}

func (tn *TsNetServer) Close() error {
return tn.TsServer.Close()
}

func (tn *TsNetServer) Start(ctx context.Context) error {
if err := tn.TsServer.Start(); err != nil {
return fmt.Errorf("error starting server: %w", err)
lc, err := tserver.LocalClient()
if err != nil {
return nil, fmt.Errorf("error starting tailscale server: %w", err)
}

// Wait for tailscale to come up...
if _, err := tn.TsServer.Up(ctx); err != nil {
return fmt.Errorf("error to come up server: %w", err)
}
return &TsNetServer{
tserver,
lc,
}, nil
}

return tn.TsServer.Start()
func (tn *TsNetServer) Close() error {
return tn.TsServer.Close()
}

0 comments on commit 278d55f

Please sign in to comment.