feat(storage): add keep field for servers
This commit is contained in:
@@ -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)
|
||||||
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user