feat(storage): add keep field for servers

This commit is contained in:
Quentin McGaw
2022-06-06 03:04:58 +00:00
parent 85e9d7d522
commit 5e659dc5b3
3 changed files with 57 additions and 10 deletions

View File

@@ -1,8 +1,10 @@
package models package models
import ( import (
"fmt"
"net" "net"
"reflect" "reflect"
"strings"
) )
type Server struct { type Server struct {
@@ -25,6 +27,7 @@ type Server struct {
Free bool `json:"free,omitempty"` Free bool `json:"free,omitempty"`
Stream bool `json:"stream,omitempty"` Stream bool `json:"stream,omitempty"`
PortForward bool `json:"port_forward,omitempty"` PortForward bool `json:"port_forward,omitempty"`
Keep bool `json:"keep,omitempty"`
IPs []net.IP `json:"ips,omitempty"` IPs []net.IP `json:"ips,omitempty"`
} }
@@ -52,3 +55,15 @@ func ipsAreEqual(a, b []net.IP) (equal bool) {
return true return true
} }
func (s *Server) Key() (key string) {
var protocols []string
if s.TCP {
protocols = append(protocols, "tcp")
}
if s.UDP {
protocols = append(protocols, "udp")
}
return fmt.Sprintf("%s-%s-%s", s.VPN, strings.Join(protocols, "-"), s.Hostname)
}

View File

@@ -62,6 +62,7 @@ func Test_Server_Equal(t *testing.T) {
Stream: true, Stream: true,
PortForward: true, PortForward: true,
IPs: []net.IP{net.IPv4(1, 2, 3, 4)}, IPs: []net.IP{net.IPv4(1, 2, 3, 4)},
Keep: true,
}, },
b: Server{ b: Server{
VPN: "vpn", VPN: "vpn",
@@ -83,6 +84,7 @@ func Test_Server_Equal(t *testing.T) {
Stream: true, Stream: true,
PortForward: true, PortForward: true,
IPs: []net.IP{net.IPv4(1, 2, 3, 4)}, IPs: []net.IP{net.IPv4(1, 2, 3, 4)},
Keep: true,
}, },
equal: true, equal: true,
}, },

View File

@@ -1,6 +1,7 @@
package storage package storage
import ( import (
"sort"
"time" "time"
"github.com/qdm12/gluetun/internal/constants/providers" "github.com/qdm12/gluetun/internal/constants/providers"
@@ -26,18 +27,47 @@ func (s *Storage) mergeServers(hardcoded, persisted models.AllServers) models.Al
func (s *Storage) mergeProviderServers(provider string, func (s *Storage) mergeProviderServers(provider string,
hardcoded, persisted models.Servers) (merged models.Servers) { hardcoded, persisted models.Servers) (merged models.Servers) {
if persisted.Timestamp <= hardcoded.Timestamp { if persisted.Timestamp > hardcoded.Timestamp {
return hardcoded diff := time.Unix(persisted.Timestamp, 0).Sub(time.Unix(hardcoded.Timestamp, 0))
if diff < 0 {
diff = -diff
}
diff = diff.Truncate(time.Second)
message := "Using " + provider + " servers from file which are " +
diff.String() + " more recent"
s.logger.Info(message)
return persisted
} }
diff := time.Unix(persisted.Timestamp, 0).Sub(time.Unix(hardcoded.Timestamp, 0)) persistedServerKeyToServer := make(map[string]models.Server)
if diff < 0 { for _, persistedServer := range persisted.Servers {
diff = -diff if persistedServer.Keep {
persistedServerKeyToServer[persistedServer.Key()] = persistedServer
}
} }
diff = diff.Truncate(time.Second)
message := "Using " + provider + " servers from file which are " +
diff.String() + " more recent"
s.logger.Info(message)
return persisted merged = hardcoded // use all fields from hardcoded
merged.Servers = make([]models.Server, 0, len(hardcoded.Servers)+len(persistedServerKeyToServer))
for _, hardcodedServer := range hardcoded.Servers {
hardcodedServerKey := hardcodedServer.Key()
persistedServerToKeep, has := persistedServerKeyToServer[hardcodedServerKey]
if has {
// Drop hardcoded server and use persisted server matching the key.
merged.Servers = append(merged.Servers, persistedServerToKeep)
delete(persistedServerKeyToServer, hardcodedServerKey)
} else {
merged.Servers = append(merged.Servers, hardcodedServer)
}
}
// Add remaining persisted servers to keep
for _, persistedServer := range persistedServerKeyToServer {
merged.Servers = append(merged.Servers, persistedServer)
}
sort.Sort(models.SortableServers(merged.Servers))
return merged
} }