Implement tunnel persistence between restarts

This commit is contained in:
Anders Pitman 2020-09-28 13:46:01 -06:00
parent 6302bba56c
commit 92affa7718
2 changed files with 63 additions and 10 deletions

View File

@ -42,6 +42,8 @@ func NewBoringProxy() *BoringProxy {
http.HandleFunc("/", p.handleAdminRequest) http.HandleFunc("/", p.handleAdminRequest)
go http.Serve(adminListener, nil) go http.Serve(adminListener, nil)
log.Println("BoringProxy ready")
return p return p
} }
@ -69,7 +71,6 @@ func (p *BoringProxy) handleAdminRequest(w http.ResponseWriter, r *http.Request)
} }
func (p *BoringProxy) handleTunnels(w http.ResponseWriter, r *http.Request) { func (p *BoringProxy) handleTunnels(w http.ResponseWriter, r *http.Request) {
fmt.Println("handleTunnels")
query := r.URL.Query() query := r.URL.Query()
@ -96,7 +97,6 @@ func (p *BoringProxy) handleTunnels(w http.ResponseWriter, r *http.Request) {
} }
func (p *BoringProxy) handleCreateTunnel(w http.ResponseWriter, r *http.Request) { func (p *BoringProxy) handleCreateTunnel(w http.ResponseWriter, r *http.Request) {
fmt.Println("handleCreateTunnel")
query := r.URL.Query() query := r.URL.Query()

View File

@ -4,18 +4,52 @@ import (
"log" "log"
"errors" "errors"
"sync" "sync"
"encoding/json"
"io/ioutil"
"github.com/caddyserver/certmagic" "github.com/caddyserver/certmagic"
) )
type Tunnel struct {
Port int `json:"port"`
}
type Tunnels map[string]*Tunnel
func NewTunnels() Tunnels {
return make(map[string]*Tunnel)
}
type TunnelManager struct { type TunnelManager struct {
tunnels map[string]int tunnels Tunnels
mutex *sync.Mutex mutex *sync.Mutex
certConfig *certmagic.Config certConfig *certmagic.Config
} }
func NewTunnelManager(certConfig *certmagic.Config) *TunnelManager { func NewTunnelManager(certConfig *certmagic.Config) *TunnelManager {
tunnels := make(map[string]int)
tunnelsJson, err := ioutil.ReadFile("tunnels.json")
if err != nil {
log.Println("failed reading tunnels.json")
tunnelsJson = []byte("{}")
}
var tunnels Tunnels
err = json.Unmarshal(tunnelsJson, &tunnels)
if err != nil {
log.Println(err)
tunnels = NewTunnels()
}
for domainName := range tunnels {
err = certConfig.ManageSync([]string{domainName})
if err != nil {
log.Println("CertMagic error at startup")
log.Println(err)
}
}
mutex := &sync.Mutex{} mutex := &sync.Mutex{}
return &TunnelManager{tunnels, mutex, certConfig} return &TunnelManager{tunnels, mutex, certConfig}
} }
@ -27,25 +61,44 @@ func (m *TunnelManager) SetTunnel(host string, port int) {
log.Println(err) log.Println(err)
} }
tunnel := &Tunnel{port}
m.mutex.Lock() m.mutex.Lock()
m.tunnels[host] = port m.tunnels[host] = tunnel
m.mutex.Unlock() m.mutex.Unlock()
m.persistTunnels()
} }
func (m *TunnelManager) DeleteTunnel(host string) { func (m *TunnelManager) DeleteTunnel(host string) {
m.mutex.Lock() m.mutex.Lock()
delete(m.tunnels, host) delete(m.tunnels, host)
m.mutex.Unlock() m.mutex.Unlock()
m.persistTunnels()
} }
func (m *TunnelManager) GetPort(serverName string) (int, error) { func (m *TunnelManager) GetPort(serverName string) (int, error) {
m.mutex.Lock() m.mutex.Lock()
port, exists := m.tunnels[serverName] tunnel, exists := m.tunnels[serverName]
m.mutex.Unlock() m.mutex.Unlock()
if !exists { if !exists {
return 0, errors.New("Doesn't exist") return 0, errors.New("Doesn't exist")
} }
return port, nil return tunnel.Port, nil
}
func (m *TunnelManager) persistTunnels() error {
tunnelsStr, err := json.MarshalIndent(m.tunnels, "", " ")
if err != nil {
return err
}
err = ioutil.WriteFile("tunnels.json", tunnelsStr, 0644)
if err != nil {
return err
}
return nil
} }