chore(all): return concrete types, accept interfaces
- Remove exported interfaces unused locally - Define interfaces to accept arguments - Return concrete types, not interfaces
This commit is contained in:
@@ -126,8 +126,8 @@ var (
|
|||||||
//nolint:gocognit,gocyclo,maintidx
|
//nolint:gocognit,gocyclo,maintidx
|
||||||
func _main(ctx context.Context, buildInfo models.BuildInformation,
|
func _main(ctx context.Context, buildInfo models.BuildInformation,
|
||||||
args []string, logger log.LoggerInterface, source sources.Source,
|
args []string, logger log.LoggerInterface, source sources.Source,
|
||||||
tun tun.Interface, netLinker netlink.NetLinker, cmder command.RunStarter,
|
tun Tun, netLinker netLinker, cmder command.RunStarter,
|
||||||
cli cli.CLIer) error {
|
cli clier) error {
|
||||||
if len(args) > 1 { // cli operation
|
if len(args) > 1 { // cli operation
|
||||||
switch args[1] {
|
switch args[1] {
|
||||||
case "healthcheck":
|
case "healthcheck":
|
||||||
@@ -390,7 +390,7 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
|
|||||||
"vpn", goroutine.OptionTimeout(time.Second))
|
"vpn", goroutine.OptionTimeout(time.Second))
|
||||||
go vpnLooper.Run(vpnCtx, vpnDone)
|
go vpnLooper.Run(vpnCtx, vpnDone)
|
||||||
|
|
||||||
updaterLooper := updater.NewLooper(allSettings.Updater,
|
updaterLooper := updater.NewLoop(allSettings.Updater,
|
||||||
providers, storage, httpClient, updaterLogger)
|
providers, storage, httpClient, updaterLogger)
|
||||||
updaterHandler, updaterCtx, updaterDone := goshutdown.NewGoRoutineHandler(
|
updaterHandler, updaterCtx, updaterDone := goshutdown.NewGoRoutineHandler(
|
||||||
"updater", goroutine.OptionTimeout(defaultShutdownTimeout))
|
"updater", goroutine.OptionTimeout(defaultShutdownTimeout))
|
||||||
@@ -411,7 +411,7 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
|
|||||||
go httpProxyLooper.Run(httpProxyCtx, httpProxyDone)
|
go httpProxyLooper.Run(httpProxyCtx, httpProxyDone)
|
||||||
otherGroupHandler.Add(httpProxyHandler)
|
otherGroupHandler.Add(httpProxyHandler)
|
||||||
|
|
||||||
shadowsocksLooper := shadowsocks.NewLooper(allSettings.Shadowsocks,
|
shadowsocksLooper := shadowsocks.NewLoop(allSettings.Shadowsocks,
|
||||||
logger.New(log.SetComponent("shadowsocks")))
|
logger.New(log.SetComponent("shadowsocks")))
|
||||||
shadowsocksHandler, shadowsocksCtx, shadowsocksDone := goshutdown.NewGoRoutineHandler(
|
shadowsocksHandler, shadowsocksCtx, shadowsocksDone := goshutdown.NewGoRoutineHandler(
|
||||||
"shadowsocks proxy", goroutine.OptionTimeout(defaultShutdownTimeout))
|
"shadowsocks proxy", goroutine.OptionTimeout(defaultShutdownTimeout))
|
||||||
@@ -480,3 +480,38 @@ func printVersions(ctx context.Context, logger infoer,
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type netLinker interface {
|
||||||
|
AddrList(link netlink.Link, family int) (
|
||||||
|
addresses []netlink.Addr, err error)
|
||||||
|
AddrAdd(link netlink.Link, addr *netlink.Addr) error
|
||||||
|
IsWireguardSupported() (ok bool, err error)
|
||||||
|
RouteList(link netlink.Link, family int) (
|
||||||
|
routes []netlink.Route, err error)
|
||||||
|
RouteAdd(route *netlink.Route) error
|
||||||
|
RouteDel(route *netlink.Route) error
|
||||||
|
RouteReplace(route *netlink.Route) error
|
||||||
|
RuleList(family int) (rules []netlink.Rule, err error)
|
||||||
|
RuleAdd(rule *netlink.Rule) error
|
||||||
|
RuleDel(rule *netlink.Rule) error
|
||||||
|
LinkList() (links []netlink.Link, err error)
|
||||||
|
LinkByName(name string) (link netlink.Link, err error)
|
||||||
|
LinkByIndex(index int) (link netlink.Link, err error)
|
||||||
|
LinkAdd(link netlink.Link) (err error)
|
||||||
|
LinkDel(link netlink.Link) (err error)
|
||||||
|
LinkSetUp(link netlink.Link) (err error)
|
||||||
|
LinkSetDown(link netlink.Link) (err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type clier interface {
|
||||||
|
ClientKey(args []string) error
|
||||||
|
FormatServers(args []string) error
|
||||||
|
OpenvpnConfig(logger cli.OpenvpnConfigLogger, source sources.Source) error
|
||||||
|
HealthCheck(ctx context.Context, source sources.Source, warner cli.Warner) error
|
||||||
|
Update(ctx context.Context, args []string, logger cli.UpdaterLogger) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type Tun interface {
|
||||||
|
Check(tunDevice string) error
|
||||||
|
Create(tunDevice string) error
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,13 +5,6 @@ import (
|
|||||||
"os/user"
|
"os/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Alpiner = (*Alpine)(nil)
|
|
||||||
|
|
||||||
type Alpiner interface {
|
|
||||||
UserCreater
|
|
||||||
VersionGetter
|
|
||||||
}
|
|
||||||
|
|
||||||
type Alpine struct {
|
type Alpine struct {
|
||||||
alpineReleasePath string
|
alpineReleasePath string
|
||||||
passwdPath string
|
passwdPath string
|
||||||
|
|||||||
@@ -12,10 +12,6 @@ var (
|
|||||||
ErrUserAlreadyExists = errors.New("user already exists")
|
ErrUserAlreadyExists = errors.New("user already exists")
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserCreater interface {
|
|
||||||
CreateUser(username string, uid int) (createdUsername string, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateUser creates a user in Alpine with the given UID.
|
// CreateUser creates a user in Alpine with the given UID.
|
||||||
func (a *Alpine) CreateUser(username string, uid int) (createdUsername string, err error) {
|
func (a *Alpine) CreateUser(username string, uid int) (createdUsername string, err error) {
|
||||||
UIDStr := strconv.Itoa(uid)
|
UIDStr := strconv.Itoa(uid)
|
||||||
|
|||||||
@@ -7,10 +7,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type VersionGetter interface {
|
|
||||||
Version(ctx context.Context) (version string, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *Alpine) Version(ctx context.Context) (version string, err error) {
|
func (a *Alpine) Version(ctx context.Context) (version string, err error) {
|
||||||
file, err := os.OpenFile(a.alpineReleasePath, os.O_RDONLY, 0)
|
file, err := os.OpenFile(a.alpineReleasePath, os.O_RDONLY, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -1,16 +1,6 @@
|
|||||||
// Package cli defines an interface CLI to run command line operations.
|
// Package cli defines an interface CLI to run command line operations.
|
||||||
package cli
|
package cli
|
||||||
|
|
||||||
var _ CLIer = (*CLI)(nil)
|
|
||||||
|
|
||||||
type CLIer interface {
|
|
||||||
ClientKeyFormatter
|
|
||||||
HealthChecker
|
|
||||||
OpenvpnConfigMaker
|
|
||||||
Updater
|
|
||||||
ServersFormatter
|
|
||||||
}
|
|
||||||
|
|
||||||
type CLI struct {
|
type CLI struct {
|
||||||
repoServersPath string
|
repoServersPath string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,10 +10,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/configuration/sources/files"
|
"github.com/qdm12/gluetun/internal/configuration/sources/files"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ClientKeyFormatter interface {
|
|
||||||
ClientKey(args []string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CLI) ClientKey(args []string) error {
|
func (c *CLI) ClientKey(args []string) error {
|
||||||
flagSet := flag.NewFlagSet("clientkey", flag.ExitOnError)
|
flagSet := flag.NewFlagSet("clientkey", flag.ExitOnError)
|
||||||
filepath := flagSet.String("path", files.OpenVPNClientKeyPath, "file path to the client.key file")
|
filepath := flagSet.String("path", files.OpenVPNClientKeyPath, "file path to the client.key file")
|
||||||
|
|||||||
@@ -15,10 +15,6 @@ import (
|
|||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServersFormatter interface {
|
|
||||||
FormatServers(args []string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrFormatNotRecognized = errors.New("format is not recognized")
|
ErrFormatNotRecognized = errors.New("format is not recognized")
|
||||||
ErrProviderUnspecified = errors.New("VPN provider to format was not specified")
|
ErrProviderUnspecified = errors.New("VPN provider to format was not specified")
|
||||||
|
|||||||
@@ -10,10 +10,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/healthcheck"
|
"github.com/qdm12/gluetun/internal/healthcheck"
|
||||||
)
|
)
|
||||||
|
|
||||||
type HealthChecker interface {
|
|
||||||
HealthCheck(ctx context.Context, source sources.Source, warner Warner) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CLI) HealthCheck(ctx context.Context, source sources.Source, warner Warner) error {
|
func (c *CLI) HealthCheck(ctx context.Context, source sources.Source, warner Warner) error {
|
||||||
// Extract the health server port from the configuration.
|
// Extract the health server port from the configuration.
|
||||||
config, err := source.ReadHealth()
|
config, err := source.ReadHealth()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -10,18 +11,18 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/constants"
|
"github.com/qdm12/gluetun/internal/constants"
|
||||||
"github.com/qdm12/gluetun/internal/provider"
|
"github.com/qdm12/gluetun/internal/provider"
|
||||||
"github.com/qdm12/gluetun/internal/storage"
|
"github.com/qdm12/gluetun/internal/storage"
|
||||||
"github.com/qdm12/gluetun/internal/updater/unzip"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type OpenvpnConfigMaker interface {
|
|
||||||
OpenvpnConfig(logger OpenvpnConfigLogger, source sources.Source) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type OpenvpnConfigLogger interface {
|
type OpenvpnConfigLogger interface {
|
||||||
Info(s string)
|
Info(s string)
|
||||||
Warn(s string)
|
Warn(s string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Unzipper interface {
|
||||||
|
FetchAndExtract(ctx context.Context, url string) (
|
||||||
|
contents map[string][]byte, err error)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *CLI) OpenvpnConfig(logger OpenvpnConfigLogger, source sources.Source) error {
|
func (c *CLI) OpenvpnConfig(logger OpenvpnConfigLogger, source sources.Source) error {
|
||||||
storage, err := storage.New(logger, constants.ServersData)
|
storage, err := storage.New(logger, constants.ServersData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -38,7 +39,7 @@ func (c *CLI) OpenvpnConfig(logger OpenvpnConfigLogger, source sources.Source) e
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Unused by this CLI command
|
// Unused by this CLI command
|
||||||
unzipper := (unzip.Unzipper)(nil)
|
unzipper := (Unzipper)(nil)
|
||||||
client := (*http.Client)(nil)
|
client := (*http.Client)(nil)
|
||||||
warner := (Warner)(nil)
|
warner := (Warner)(nil)
|
||||||
|
|
||||||
|
|||||||
@@ -25,10 +25,6 @@ var (
|
|||||||
ErrNoProviderSpecified = errors.New("no provider was specified")
|
ErrNoProviderSpecified = errors.New("no provider was specified")
|
||||||
)
|
)
|
||||||
|
|
||||||
type Updater interface {
|
|
||||||
Update(ctx context.Context, args []string, logger UpdaterLogger) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type UpdaterLogger interface {
|
type UpdaterLogger interface {
|
||||||
Info(s string)
|
Info(s string)
|
||||||
Warn(s string)
|
Warn(s string)
|
||||||
|
|||||||
29
internal/dns/interfaces.go
Normal file
29
internal/dns/interfaces.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package dns
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/qdm12/dns/pkg/unbound"
|
||||||
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Configurator interface {
|
||||||
|
SetupFiles(ctx context.Context) error
|
||||||
|
MakeUnboundConf(settings unbound.Settings) (err error)
|
||||||
|
Start(ctx context.Context, verbosityDetailsLevel uint8) (
|
||||||
|
stdoutLines, stderrLines chan string, waitError chan error, err error)
|
||||||
|
Version(ctx context.Context) (version string, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type statusManager interface {
|
||||||
|
GetStatus() (status models.LoopStatus)
|
||||||
|
SetStatus(status models.LoopStatus)
|
||||||
|
ApplyStatus(ctx context.Context, status models.LoopStatus) (
|
||||||
|
outcome string, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type stateManager interface {
|
||||||
|
GetSettings() (settings settings.DNS)
|
||||||
|
SetSettings(ctx context.Context, settings settings.DNS) (outcome string)
|
||||||
|
}
|
||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/qdm12/dns/pkg/blacklist"
|
"github.com/qdm12/dns/pkg/blacklist"
|
||||||
"github.com/qdm12/dns/pkg/unbound"
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
"github.com/qdm12/gluetun/internal/constants"
|
"github.com/qdm12/gluetun/internal/constants"
|
||||||
"github.com/qdm12/gluetun/internal/dns/state"
|
"github.com/qdm12/gluetun/internal/dns/state"
|
||||||
@@ -15,20 +14,10 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/models"
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Looper = (*Loop)(nil)
|
|
||||||
|
|
||||||
type Looper interface {
|
|
||||||
Runner
|
|
||||||
RestartTickerRunner
|
|
||||||
loopstate.Applier
|
|
||||||
loopstate.Getter
|
|
||||||
SettingsGetSetter
|
|
||||||
}
|
|
||||||
|
|
||||||
type Loop struct {
|
type Loop struct {
|
||||||
statusManager loopstate.Manager
|
statusManager statusManager
|
||||||
state state.Manager
|
state stateManager
|
||||||
conf unbound.Configurator
|
conf Configurator
|
||||||
resolvConf string
|
resolvConf string
|
||||||
blockBuilder blacklist.Builder
|
blockBuilder blacklist.Builder
|
||||||
client *http.Client
|
client *http.Client
|
||||||
@@ -46,7 +35,7 @@ type Loop struct {
|
|||||||
|
|
||||||
const defaultBackoffTime = 10 * time.Second
|
const defaultBackoffTime = 10 * time.Second
|
||||||
|
|
||||||
func NewLoop(conf unbound.Configurator, settings settings.DNS,
|
func NewLoop(conf Configurator, settings settings.DNS,
|
||||||
client *http.Client, logger Logger) *Loop {
|
client *http.Client, logger Logger) *Loop {
|
||||||
start := make(chan struct{})
|
start := make(chan struct{})
|
||||||
running := make(chan models.LoopStatus)
|
running := make(chan models.LoopStatus)
|
||||||
|
|||||||
@@ -7,10 +7,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/constants"
|
"github.com/qdm12/gluetun/internal/constants"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Runner interface {
|
|
||||||
Run(ctx context.Context, done chan<- struct{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
|
func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
|
|
||||||
|
|||||||
@@ -6,22 +6,8 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SettingsGetSetter interface {
|
|
||||||
SettingsGetter
|
|
||||||
SettingsSetter
|
|
||||||
}
|
|
||||||
|
|
||||||
type SettingsGetter interface {
|
|
||||||
GetSettings() (settings settings.DNS)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Loop) GetSettings() (settings settings.DNS) { return l.state.GetSettings() }
|
func (l *Loop) GetSettings() (settings settings.DNS) { return l.state.GetSettings() }
|
||||||
|
|
||||||
type SettingsSetter interface {
|
|
||||||
SetSettings(ctx context.Context, settings settings.DNS) (
|
|
||||||
outcome string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Loop) SetSettings(ctx context.Context, settings settings.DNS) (
|
func (l *Loop) SetSettings(ctx context.Context, settings settings.DNS) (
|
||||||
outcome string) {
|
outcome string) {
|
||||||
return l.state.SetSettings(ctx, settings)
|
return l.state.SetSettings(ctx, settings)
|
||||||
|
|||||||
@@ -8,12 +8,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/constants"
|
"github.com/qdm12/gluetun/internal/constants"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SettingsGetSetter interface {
|
|
||||||
GetSettings() (settings settings.DNS)
|
|
||||||
SetSettings(ctx context.Context,
|
|
||||||
settings settings.DNS) (outcome string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *State) GetSettings() (settings settings.DNS) {
|
func (s *State) GetSettings() (settings settings.DNS) {
|
||||||
s.settingsMu.RLock()
|
s.settingsMu.RLock()
|
||||||
defer s.settingsMu.RUnlock()
|
defer s.settingsMu.RUnlock()
|
||||||
|
|||||||
@@ -1,19 +1,14 @@
|
|||||||
package state
|
package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
"github.com/qdm12/gluetun/internal/loopstate"
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Manager = (*State)(nil)
|
func New(statusApplier StatusApplier,
|
||||||
|
|
||||||
type Manager interface {
|
|
||||||
SettingsGetSetter
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(statusApplier loopstate.Applier,
|
|
||||||
settings settings.DNS,
|
settings settings.DNS,
|
||||||
updateTicker chan<- struct{}) *State {
|
updateTicker chan<- struct{}) *State {
|
||||||
return &State{
|
return &State{
|
||||||
@@ -24,10 +19,15 @@ func New(statusApplier loopstate.Applier,
|
|||||||
}
|
}
|
||||||
|
|
||||||
type State struct {
|
type State struct {
|
||||||
statusApplier loopstate.Applier
|
statusApplier StatusApplier
|
||||||
|
|
||||||
settings settings.DNS
|
settings settings.DNS
|
||||||
settingsMu sync.RWMutex
|
settingsMu sync.RWMutex
|
||||||
|
|
||||||
updateTicker chan<- struct{}
|
updateTicker chan<- struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type StatusApplier interface {
|
||||||
|
ApplyStatus(ctx context.Context, status models.LoopStatus) (
|
||||||
|
outcome string, err error)
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,10 +7,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/constants"
|
"github.com/qdm12/gluetun/internal/constants"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RestartTickerRunner interface {
|
|
||||||
RunRestartTicker(ctx context.Context, done chan<- struct{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Loop) RunRestartTicker(ctx context.Context, done chan<- struct{}) {
|
func (l *Loop) RunRestartTicker(ctx context.Context, done chan<- struct{}) {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
// Timer that acts as a ticker
|
// Timer that acts as a ticker
|
||||||
|
|||||||
@@ -5,10 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Enabler interface {
|
|
||||||
SetEnabled(ctx context.Context, enabled bool) (err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) SetEnabled(ctx context.Context, enabled bool) (err error) {
|
func (c *Config) SetEnabled(ctx context.Context, enabled bool) (err error) {
|
||||||
c.stateMutex.Lock()
|
c.stateMutex.Lock()
|
||||||
defer c.stateMutex.Unlock()
|
defer c.stateMutex.Unlock()
|
||||||
|
|||||||
@@ -12,16 +12,6 @@ import (
|
|||||||
"github.com/qdm12/golibs/command"
|
"github.com/qdm12/golibs/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Configurator = (*Config)(nil)
|
|
||||||
|
|
||||||
// Configurator allows to change firewall rules and modify network routes.
|
|
||||||
type Configurator interface {
|
|
||||||
Enabler
|
|
||||||
VPNConnectionSetter
|
|
||||||
PortAllower
|
|
||||||
OutboundSubnetsSetter
|
|
||||||
}
|
|
||||||
|
|
||||||
type Config struct { //nolint:maligned
|
type Config struct { //nolint:maligned
|
||||||
runner command.Runner
|
runner command.Runner
|
||||||
logger Logger
|
logger Logger
|
||||||
|
|||||||
@@ -8,10 +8,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/subnet"
|
"github.com/qdm12/gluetun/internal/subnet"
|
||||||
)
|
)
|
||||||
|
|
||||||
type OutboundSubnetsSetter interface {
|
|
||||||
SetOutboundSubnets(ctx context.Context, subnets []net.IPNet) (err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) SetOutboundSubnets(ctx context.Context, subnets []net.IPNet) (err error) {
|
func (c *Config) SetOutboundSubnets(ctx context.Context, subnets []net.IPNet) (err error) {
|
||||||
c.stateMutex.Lock()
|
c.stateMutex.Lock()
|
||||||
defer c.stateMutex.Unlock()
|
defer c.stateMutex.Unlock()
|
||||||
|
|||||||
@@ -6,11 +6,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PortAllower interface {
|
|
||||||
SetAllowedPort(ctx context.Context, port uint16, intf string) (err error)
|
|
||||||
RemoveAllowedPort(ctx context.Context, port uint16) (err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) SetAllowedPort(ctx context.Context, port uint16, intf string) (err error) {
|
func (c *Config) SetAllowedPort(ctx context.Context, port uint16, intf string) (err error) {
|
||||||
c.stateMutex.Lock()
|
c.stateMutex.Lock()
|
||||||
defer c.stateMutex.Unlock()
|
defer c.stateMutex.Unlock()
|
||||||
|
|||||||
@@ -7,11 +7,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/models"
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type VPNConnectionSetter interface {
|
|
||||||
SetVPNConnection(ctx context.Context,
|
|
||||||
connection models.Connection, vpnIntf string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) SetVPNConnection(ctx context.Context,
|
func (c *Config) SetVPNConnection(ctx context.Context,
|
||||||
connection models.Connection, vpnIntf string) (err error) {
|
connection models.Connection, vpnIntf string) (err error) {
|
||||||
c.stateMutex.Lock()
|
c.stateMutex.Lock()
|
||||||
|
|||||||
@@ -12,12 +12,6 @@ var (
|
|||||||
ErrHTTPStatusNotOK = errors.New("HTTP response status is not OK")
|
ErrHTTPStatusNotOK = errors.New("HTTP response status is not OK")
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Checker = (*Client)(nil)
|
|
||||||
|
|
||||||
type Checker interface {
|
|
||||||
Check(ctx context.Context, url string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/constants"
|
"github.com/qdm12/gluetun/internal/constants"
|
||||||
"github.com/qdm12/gluetun/internal/vpn"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type vpnHealth struct {
|
type vpnHealth struct {
|
||||||
looper vpn.Looper
|
loop StatusApplier
|
||||||
healthyWait time.Duration
|
healthyWait time.Duration
|
||||||
healthyTimer *time.Timer
|
healthyTimer *time.Timer
|
||||||
}
|
}
|
||||||
@@ -17,8 +16,8 @@ type vpnHealth struct {
|
|||||||
func (s *Server) onUnhealthyVPN(ctx context.Context) {
|
func (s *Server) onUnhealthyVPN(ctx context.Context) {
|
||||||
s.logger.Info("program has been unhealthy for " +
|
s.logger.Info("program has been unhealthy for " +
|
||||||
s.vpn.healthyWait.String() + ": restarting VPN")
|
s.vpn.healthyWait.String() + ": restarting VPN")
|
||||||
_, _ = s.vpn.looper.ApplyStatus(ctx, constants.Stopped)
|
_, _ = s.vpn.loop.ApplyStatus(ctx, constants.Stopped)
|
||||||
_, _ = s.vpn.looper.ApplyStatus(ctx, constants.Running)
|
_, _ = s.vpn.loop.ApplyStatus(ctx, constants.Running)
|
||||||
s.vpn.healthyWait += *s.config.VPN.Addition
|
s.vpn.healthyWait += *s.config.VPN.Addition
|
||||||
s.vpn.healthyTimer = time.NewTimer(s.vpn.healthyWait)
|
s.vpn.healthyTimer = time.NewTimer(s.vpn.healthyWait)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,15 +5,9 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
"github.com/qdm12/gluetun/internal/vpn"
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ ServerRunner = (*Server)(nil)
|
|
||||||
|
|
||||||
type ServerRunner interface {
|
|
||||||
Run(ctx context.Context, done chan<- struct{})
|
|
||||||
}
|
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
logger Logger
|
logger Logger
|
||||||
handler *handler
|
handler *handler
|
||||||
@@ -23,15 +17,20 @@ type Server struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(config settings.Health,
|
func NewServer(config settings.Health,
|
||||||
logger Logger, vpnLooper vpn.Looper) *Server {
|
logger Logger, vpnLoop StatusApplier) *Server {
|
||||||
return &Server{
|
return &Server{
|
||||||
logger: logger,
|
logger: logger,
|
||||||
handler: newHandler(),
|
handler: newHandler(),
|
||||||
dialer: &net.Dialer{},
|
dialer: &net.Dialer{},
|
||||||
config: config,
|
config: config,
|
||||||
vpn: vpnHealth{
|
vpn: vpnHealth{
|
||||||
looper: vpnLooper,
|
loop: vpnLoop,
|
||||||
healthyWait: *config.VPN.Initial,
|
healthyWait: *config.VPN.Initial,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type StatusApplier interface {
|
||||||
|
ApplyStatus(ctx context.Context, status models.LoopStatus) (
|
||||||
|
outcome string, err error)
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,18 +12,9 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/models"
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Looper = (*Loop)(nil)
|
|
||||||
|
|
||||||
type Looper interface {
|
|
||||||
Runner
|
|
||||||
loopstate.Getter
|
|
||||||
loopstate.Applier
|
|
||||||
SettingsGetSetter
|
|
||||||
}
|
|
||||||
|
|
||||||
type Loop struct {
|
type Loop struct {
|
||||||
statusManager loopstate.Manager
|
statusManager statusManager
|
||||||
state state.Manager
|
state StateManager
|
||||||
// Other objects
|
// Other objects
|
||||||
logger Logger
|
logger Logger
|
||||||
// Internal channels and locks
|
// Internal channels and locks
|
||||||
@@ -34,6 +25,18 @@ type Loop struct {
|
|||||||
backoffTime time.Duration
|
backoffTime time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type statusManager interface {
|
||||||
|
GetStatus() (status models.LoopStatus)
|
||||||
|
SetStatus(status models.LoopStatus)
|
||||||
|
ApplyStatus(ctx context.Context, status models.LoopStatus) (
|
||||||
|
outcome string, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type StateManager interface {
|
||||||
|
GetSettings() settings.HTTPProxy
|
||||||
|
SetSettings(ctx context.Context, settings settings.HTTPProxy) (outcome string)
|
||||||
|
}
|
||||||
|
|
||||||
const defaultBackoffTime = 10 * time.Second
|
const defaultBackoffTime = 10 * time.Second
|
||||||
|
|
||||||
func NewLoop(logger Logger, settings settings.HTTPProxy) *Loop {
|
func NewLoop(logger Logger, settings settings.HTTPProxy) *Loop {
|
||||||
|
|||||||
@@ -6,10 +6,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/constants"
|
"github.com/qdm12/gluetun/internal/constants"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Runner interface {
|
|
||||||
Run(ctx context.Context, done chan<- struct{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
|
func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
"github.com/qdm12/gluetun/internal/httpproxy/state"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SettingsGetSetter = state.SettingsGetSetter
|
|
||||||
|
|
||||||
func (l *Loop) GetSettings() (settings settings.HTTPProxy) {
|
func (l *Loop) GetSettings() (settings settings.HTTPProxy) {
|
||||||
return l.state.GetSettings()
|
return l.state.GetSettings()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,26 +8,12 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/constants"
|
"github.com/qdm12/gluetun/internal/constants"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SettingsGetSetter interface {
|
|
||||||
SettingsGetter
|
|
||||||
SettingsSetter
|
|
||||||
}
|
|
||||||
|
|
||||||
type SettingsGetter interface {
|
|
||||||
GetSettings() (settings settings.HTTPProxy)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *State) GetSettings() (settings settings.HTTPProxy) {
|
func (s *State) GetSettings() (settings settings.HTTPProxy) {
|
||||||
s.settingsMu.RLock()
|
s.settingsMu.RLock()
|
||||||
defer s.settingsMu.RUnlock()
|
defer s.settingsMu.RUnlock()
|
||||||
return s.settings
|
return s.settings
|
||||||
}
|
}
|
||||||
|
|
||||||
type SettingsSetter interface {
|
|
||||||
SetSettings(ctx context.Context,
|
|
||||||
settings settings.HTTPProxy) (outcome string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *State) SetSettings(ctx context.Context,
|
func (s *State) SetSettings(ctx context.Context,
|
||||||
settings settings.HTTPProxy) (outcome string) {
|
settings settings.HTTPProxy) (outcome string) {
|
||||||
s.settingsMu.Lock()
|
s.settingsMu.Lock()
|
||||||
|
|||||||
@@ -1,19 +1,14 @@
|
|||||||
package state
|
package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
"github.com/qdm12/gluetun/internal/loopstate"
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Manager = (*State)(nil)
|
func New(statusApplier StatusApplier,
|
||||||
|
|
||||||
type Manager interface {
|
|
||||||
SettingsGetSetter
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(statusApplier loopstate.Applier,
|
|
||||||
settings settings.HTTPProxy) *State {
|
settings settings.HTTPProxy) *State {
|
||||||
return &State{
|
return &State{
|
||||||
statusApplier: statusApplier,
|
statusApplier: statusApplier,
|
||||||
@@ -22,7 +17,12 @@ func New(statusApplier loopstate.Applier,
|
|||||||
}
|
}
|
||||||
|
|
||||||
type State struct {
|
type State struct {
|
||||||
statusApplier loopstate.Applier
|
statusApplier StatusApplier
|
||||||
settings settings.HTTPProxy
|
settings settings.HTTPProxy
|
||||||
settingsMu sync.RWMutex
|
settingsMu sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type StatusApplier interface {
|
||||||
|
ApplyStatus(ctx context.Context, status models.LoopStatus) (
|
||||||
|
outcome string, err error)
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,30 +2,11 @@
|
|||||||
package httpserver
|
package httpserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Interface = (*Server)(nil)
|
|
||||||
|
|
||||||
// Interface is the HTTP server composite interface.
|
|
||||||
type Interface interface {
|
|
||||||
Runner
|
|
||||||
AddressGetter
|
|
||||||
}
|
|
||||||
|
|
||||||
// Runner is the interface for an HTTP server with a Run method.
|
|
||||||
type Runner interface {
|
|
||||||
Run(ctx context.Context, ready chan<- struct{}, done chan<- struct{})
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddressGetter obtains the address the HTTP server is listening on.
|
|
||||||
type AddressGetter interface {
|
|
||||||
GetAddress() (address string)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Server is an HTTP server implementation, which uses
|
// Server is an HTTP server implementation, which uses
|
||||||
// the HTTP handler provided.
|
// the HTTP handler provided.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
|
|||||||
@@ -9,11 +9,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/models"
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Applier interface {
|
|
||||||
ApplyStatus(ctx context.Context, status models.LoopStatus) (
|
|
||||||
outcome string, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
var ErrInvalidStatus = errors.New("invalid status")
|
var ErrInvalidStatus = errors.New("invalid status")
|
||||||
|
|
||||||
// ApplyStatus sends signals to the running loop depending on the
|
// ApplyStatus sends signals to the running loop depending on the
|
||||||
|
|||||||
@@ -2,10 +2,6 @@ package loopstate
|
|||||||
|
|
||||||
import "github.com/qdm12/gluetun/internal/models"
|
import "github.com/qdm12/gluetun/internal/models"
|
||||||
|
|
||||||
type Getter interface {
|
|
||||||
GetStatus() (status models.LoopStatus)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetStatus gets the status thread safely.
|
// GetStatus gets the status thread safely.
|
||||||
func (s *State) GetStatus() (status models.LoopStatus) {
|
func (s *State) GetStatus() (status models.LoopStatus) {
|
||||||
s.statusMu.RLock()
|
s.statusMu.RLock()
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
package loopstate
|
package loopstate
|
||||||
|
|
||||||
type Locker interface {
|
|
||||||
Lock()
|
|
||||||
Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *State) Lock() { s.loopMu.Lock() }
|
func (s *State) Lock() { s.loopMu.Lock() }
|
||||||
func (s *State) Unlock() { s.loopMu.Unlock() }
|
func (s *State) Unlock() { s.loopMu.Unlock() }
|
||||||
|
|||||||
@@ -2,10 +2,6 @@ package loopstate
|
|||||||
|
|
||||||
import "github.com/qdm12/gluetun/internal/models"
|
import "github.com/qdm12/gluetun/internal/models"
|
||||||
|
|
||||||
type Setter interface {
|
|
||||||
SetStatus(status models.LoopStatus)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetStatus sets the status thread safely.
|
// SetStatus sets the status thread safely.
|
||||||
// It should only be called by the loop internal code since
|
// It should only be called by the loop internal code since
|
||||||
// it does not interact with the loop code directly.
|
// it does not interact with the loop code directly.
|
||||||
|
|||||||
@@ -6,15 +6,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/models"
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Manager = (*State)(nil)
|
|
||||||
|
|
||||||
type Manager interface {
|
|
||||||
Locker
|
|
||||||
Getter
|
|
||||||
Setter
|
|
||||||
Applier
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(status models.LoopStatus,
|
func New(status models.LoopStatus,
|
||||||
start chan<- struct{}, running <-chan models.LoopStatus,
|
start chan<- struct{}, running <-chan models.LoopStatus,
|
||||||
stop chan<- struct{}, stopped <-chan struct{}) *State {
|
stop chan<- struct{}, stopped <-chan struct{}) *State {
|
||||||
|
|||||||
@@ -4,14 +4,6 @@ import "github.com/vishvananda/netlink"
|
|||||||
|
|
||||||
type Addr = netlink.Addr
|
type Addr = netlink.Addr
|
||||||
|
|
||||||
var _ Addresser = (*NetLink)(nil)
|
|
||||||
|
|
||||||
type Addresser interface {
|
|
||||||
AddrList(link netlink.Link, family int) (
|
|
||||||
addresses []netlink.Addr, err error)
|
|
||||||
AddrAdd(link netlink.Link, addr *netlink.Addr) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *NetLink) AddrList(link Link, family int) (
|
func (n *NetLink) AddrList(link Link, family int) (
|
||||||
addresses []Addr, err error) {
|
addresses []Addr, err error) {
|
||||||
return netlink.AddrList(link, family)
|
return netlink.AddrList(link, family)
|
||||||
|
|||||||
@@ -13,10 +13,6 @@ const (
|
|||||||
FAMILY_V6 = netlink.FAMILY_V6
|
FAMILY_V6 = netlink.FAMILY_V6
|
||||||
)
|
)
|
||||||
|
|
||||||
type WireguardChecker interface {
|
|
||||||
IsWireguardSupported() (ok bool, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *NetLink) IsWireguardSupported() (ok bool, err error) {
|
func (n *NetLink) IsWireguardSupported() (ok bool, err error) {
|
||||||
families, err := netlink.GenlFamilyList()
|
families, err := netlink.GenlFamilyList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
package netlink
|
|
||||||
|
|
||||||
//go:generate mockgen -destination=mock_$GOPACKAGE/$GOFILE . NetLinker
|
|
||||||
|
|
||||||
var _ NetLinker = (*NetLink)(nil)
|
|
||||||
|
|
||||||
type NetLinker interface {
|
|
||||||
Addresser
|
|
||||||
Linker
|
|
||||||
Router
|
|
||||||
Ruler
|
|
||||||
WireguardChecker
|
|
||||||
}
|
|
||||||
@@ -8,18 +8,6 @@ type (
|
|||||||
Wireguard = netlink.Wireguard
|
Wireguard = netlink.Wireguard
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Linker = (*NetLink)(nil)
|
|
||||||
|
|
||||||
type Linker interface {
|
|
||||||
LinkList() (links []netlink.Link, err error)
|
|
||||||
LinkByName(name string) (link netlink.Link, err error)
|
|
||||||
LinkByIndex(index int) (link netlink.Link, err error)
|
|
||||||
LinkAdd(link netlink.Link) (err error)
|
|
||||||
LinkDel(link netlink.Link) (err error)
|
|
||||||
LinkSetUp(link netlink.Link) (err error)
|
|
||||||
LinkSetDown(link netlink.Link) (err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *NetLink) LinkList() (links []Link, err error) {
|
func (n *NetLink) LinkList() (links []Link, err error) {
|
||||||
return netlink.LinkList()
|
return netlink.LinkList()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,16 +4,6 @@ import "github.com/vishvananda/netlink"
|
|||||||
|
|
||||||
type Route = netlink.Route
|
type Route = netlink.Route
|
||||||
|
|
||||||
var _ Router = (*NetLink)(nil)
|
|
||||||
|
|
||||||
type Router interface {
|
|
||||||
RouteList(link netlink.Link, family int) (
|
|
||||||
routes []netlink.Route, err error)
|
|
||||||
RouteAdd(route *netlink.Route) error
|
|
||||||
RouteDel(route *netlink.Route) error
|
|
||||||
RouteReplace(route *netlink.Route) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *NetLink) RouteList(link Link, family int) (
|
func (n *NetLink) RouteList(link Link, family int) (
|
||||||
routes []Route, err error) {
|
routes []Route, err error) {
|
||||||
return netlink.RouteList(link, family)
|
return netlink.RouteList(link, family)
|
||||||
|
|||||||
@@ -8,14 +8,6 @@ func NewRule() *Rule {
|
|||||||
return netlink.NewRule()
|
return netlink.NewRule()
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Ruler = (*NetLink)(nil)
|
|
||||||
|
|
||||||
type Ruler interface {
|
|
||||||
RuleList(family int) (rules []netlink.Rule, err error)
|
|
||||||
RuleAdd(rule *netlink.Rule) error
|
|
||||||
RuleDel(rule *netlink.Rule) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *NetLink) RuleList(family int) (rules []Rule, err error) {
|
func (n *NetLink) RuleList(family int) (rules []Rule, err error) {
|
||||||
return netlink.RuleList(family)
|
return netlink.RuleList(family)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AuthWriter interface {
|
|
||||||
WriteAuthFile(user, password string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteAuthFile writes the OpenVPN auth file to disk with the right permissions.
|
// WriteAuthFile writes the OpenVPN auth file to disk with the right permissions.
|
||||||
func (c *Configurator) WriteAuthFile(user, password string) error {
|
func (c *Configurator) WriteAuthFile(user, password string) error {
|
||||||
file, err := os.Open(c.authFilePath)
|
file, err := os.Open(c.authFilePath)
|
||||||
|
|||||||
@@ -5,10 +5,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Writer interface {
|
|
||||||
WriteConfig(lines []string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Configurator) WriteConfig(lines []string) error {
|
func (c *Configurator) WriteConfig(lines []string) error {
|
||||||
file, err := os.OpenFile(c.configPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
|
file, err := os.OpenFile(c.configPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -1,16 +1,5 @@
|
|||||||
package extract
|
package extract
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/qdm12/gluetun/internal/models"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ Interface = (*Extractor)(nil)
|
|
||||||
|
|
||||||
type Interface interface {
|
|
||||||
Data(filepath string) (lines []string,
|
|
||||||
connection models.Connection, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Extractor struct{}
|
type Extractor struct{}
|
||||||
|
|
||||||
func New() *Extractor {
|
func New() *Extractor {
|
||||||
|
|||||||
@@ -5,14 +5,6 @@ import (
|
|||||||
"github.com/qdm12/golibs/command"
|
"github.com/qdm12/golibs/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Interface = (*Configurator)(nil)
|
|
||||||
|
|
||||||
type Interface interface {
|
|
||||||
VersionGetter
|
|
||||||
AuthWriter
|
|
||||||
Writer
|
|
||||||
}
|
|
||||||
|
|
||||||
type Configurator struct {
|
type Configurator struct {
|
||||||
logger Infoer
|
logger Infoer
|
||||||
cmder command.RunStarter
|
cmder command.RunStarter
|
||||||
|
|||||||
@@ -8,11 +8,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type VersionGetter interface {
|
|
||||||
Version24(ctx context.Context) (version string, err error)
|
|
||||||
Version25(ctx context.Context) (version string, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Configurator) Version24(ctx context.Context) (version string, err error) {
|
func (c *Configurator) Version24(ctx context.Context) (version string, err error) {
|
||||||
return c.version(ctx, binOpenvpn24)
|
return c.version(ctx, binOpenvpn24)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
package portforward
|
package portforward
|
||||||
|
|
||||||
import "github.com/qdm12/gluetun/internal/portforward/state"
|
|
||||||
|
|
||||||
type Getter = state.PortForwardedGetter
|
|
||||||
|
|
||||||
func (l *Loop) GetPortForwarded() (port uint16) {
|
func (l *Loop) GetPortForwarded() (port uint16) {
|
||||||
return l.state.GetPortForwarded()
|
return l.state.GetPortForwarded()
|
||||||
}
|
}
|
||||||
|
|||||||
30
internal/portforward/interfaces.go
Normal file
30
internal/portforward/interfaces.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package portforward
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PortAllower interface {
|
||||||
|
SetAllowedPort(ctx context.Context, port uint16, intf string) (err error)
|
||||||
|
RemoveAllowedPort(ctx context.Context, port uint16) (err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type statusManager interface {
|
||||||
|
GetStatus() (status models.LoopStatus)
|
||||||
|
SetStatus(status models.LoopStatus)
|
||||||
|
ApplyStatus(ctx context.Context, status models.LoopStatus) (
|
||||||
|
outcome string, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type StateManager interface {
|
||||||
|
GetSettings() (settings settings.PortForwarding)
|
||||||
|
SetSettings(ctx context.Context,
|
||||||
|
settings settings.PortForwarding) (outcome string)
|
||||||
|
GetPortForwarded() (port uint16)
|
||||||
|
SetPortForwarded(port uint16)
|
||||||
|
GetStartData() (startData StartData)
|
||||||
|
SetStartData(startData StartData)
|
||||||
|
}
|
||||||
@@ -7,28 +7,17 @@ import (
|
|||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
"github.com/qdm12/gluetun/internal/constants"
|
"github.com/qdm12/gluetun/internal/constants"
|
||||||
"github.com/qdm12/gluetun/internal/firewall"
|
|
||||||
"github.com/qdm12/gluetun/internal/loopstate"
|
"github.com/qdm12/gluetun/internal/loopstate"
|
||||||
"github.com/qdm12/gluetun/internal/models"
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
"github.com/qdm12/gluetun/internal/portforward/state"
|
"github.com/qdm12/gluetun/internal/portforward/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Looper = (*Loop)(nil)
|
|
||||||
|
|
||||||
type Looper interface {
|
|
||||||
Runner
|
|
||||||
loopstate.Getter
|
|
||||||
StartStopper
|
|
||||||
SettingsGetSetter
|
|
||||||
Getter
|
|
||||||
}
|
|
||||||
|
|
||||||
type Loop struct {
|
type Loop struct {
|
||||||
statusManager loopstate.Manager
|
statusManager statusManager
|
||||||
state state.Manager
|
state StateManager
|
||||||
// Objects
|
// Objects
|
||||||
client *http.Client
|
client *http.Client
|
||||||
portAllower firewall.PortAllower
|
portAllower PortAllower
|
||||||
logger Logger
|
logger Logger
|
||||||
// Internal channels and locks
|
// Internal channels and locks
|
||||||
start chan struct{}
|
start chan struct{}
|
||||||
@@ -43,7 +32,7 @@ type Loop struct {
|
|||||||
const defaultBackoffTime = 5 * time.Second
|
const defaultBackoffTime = 5 * time.Second
|
||||||
|
|
||||||
func NewLoop(settings settings.PortForwarding,
|
func NewLoop(settings settings.PortForwarding,
|
||||||
client *http.Client, portAllower firewall.PortAllower,
|
client *http.Client, portAllower PortAllower,
|
||||||
logger Logger) *Loop {
|
logger Logger) *Loop {
|
||||||
start := make(chan struct{})
|
start := make(chan struct{})
|
||||||
running := make(chan models.LoopStatus)
|
running := make(chan models.LoopStatus)
|
||||||
|
|||||||
@@ -7,10 +7,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/constants"
|
"github.com/qdm12/gluetun/internal/constants"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Runner interface {
|
|
||||||
Run(ctx context.Context, done chan<- struct{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
|
func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
"github.com/qdm12/gluetun/internal/portforward/state"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SettingsGetSetter = state.SettingsGetSetter
|
|
||||||
|
|
||||||
func (l *Loop) GetSettings() (settings settings.PortForwarding) {
|
func (l *Loop) GetSettings() (settings settings.PortForwarding) {
|
||||||
return l.state.GetSettings()
|
return l.state.GetSettings()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,5 @@
|
|||||||
package state
|
package state
|
||||||
|
|
||||||
type PortForwardedGetterSetter interface {
|
|
||||||
PortForwardedGetter
|
|
||||||
SetPortForwarded(port uint16)
|
|
||||||
}
|
|
||||||
|
|
||||||
type PortForwardedGetter interface {
|
|
||||||
GetPortForwarded() (port uint16)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPortForwarded is used by the control HTTP server
|
// GetPortForwarded is used by the control HTTP server
|
||||||
// to obtain the port currently forwarded.
|
// to obtain the port currently forwarded.
|
||||||
func (s *State) GetPortForwarded() (port uint16) {
|
func (s *State) GetPortForwarded() (port uint16) {
|
||||||
|
|||||||
@@ -9,12 +9,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/constants"
|
"github.com/qdm12/gluetun/internal/constants"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SettingsGetSetter interface {
|
|
||||||
GetSettings() (settings settings.PortForwarding)
|
|
||||||
SetSettings(ctx context.Context,
|
|
||||||
settings settings.PortForwarding) (outcome string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *State) GetSettings() (settings settings.PortForwarding) {
|
func (s *State) GetSettings() (settings settings.PortForwarding) {
|
||||||
s.settingsMu.RLock()
|
s.settingsMu.RLock()
|
||||||
defer s.settingsMu.RUnlock()
|
defer s.settingsMu.RUnlock()
|
||||||
|
|||||||
@@ -13,25 +13,12 @@ type StartData struct {
|
|||||||
Interface string // tun0 for example
|
Interface string // tun0 for example
|
||||||
}
|
}
|
||||||
|
|
||||||
type StartDataGetterSetter interface {
|
|
||||||
StartDataGetter
|
|
||||||
StartDataSetter
|
|
||||||
}
|
|
||||||
|
|
||||||
type StartDataGetter interface {
|
|
||||||
GetStartData() (startData StartData)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *State) GetStartData() (startData StartData) {
|
func (s *State) GetStartData() (startData StartData) {
|
||||||
s.startDataMu.RLock()
|
s.startDataMu.RLock()
|
||||||
defer s.startDataMu.RUnlock()
|
defer s.startDataMu.RUnlock()
|
||||||
return s.startData
|
return s.startData
|
||||||
}
|
}
|
||||||
|
|
||||||
type StartDataSetter interface {
|
|
||||||
SetStartData(startData StartData)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *State) SetStartData(startData StartData) {
|
func (s *State) SetStartData(startData StartData) {
|
||||||
s.startDataMu.Lock()
|
s.startDataMu.Lock()
|
||||||
defer s.startDataMu.Unlock()
|
defer s.startDataMu.Unlock()
|
||||||
|
|||||||
@@ -1,21 +1,14 @@
|
|||||||
package state
|
package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
"github.com/qdm12/gluetun/internal/loopstate"
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Manager = (*State)(nil)
|
func New(statusApplier StatusApplier,
|
||||||
|
|
||||||
type Manager interface {
|
|
||||||
SettingsGetSetter
|
|
||||||
PortForwardedGetterSetter
|
|
||||||
StartDataGetterSetter
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(statusApplier loopstate.Applier,
|
|
||||||
settings settings.PortForwarding) *State {
|
settings settings.PortForwarding) *State {
|
||||||
return &State{
|
return &State{
|
||||||
statusApplier: statusApplier,
|
statusApplier: statusApplier,
|
||||||
@@ -24,7 +17,7 @@ func New(statusApplier loopstate.Applier,
|
|||||||
}
|
}
|
||||||
|
|
||||||
type State struct {
|
type State struct {
|
||||||
statusApplier loopstate.Applier
|
statusApplier StatusApplier
|
||||||
|
|
||||||
settings settings.PortForwarding
|
settings settings.PortForwarding
|
||||||
settingsMu sync.RWMutex
|
settingsMu sync.RWMutex
|
||||||
@@ -35,3 +28,8 @@ type State struct {
|
|||||||
startData StartData
|
startData StartData
|
||||||
startDataMu sync.RWMutex
|
startDataMu sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type StatusApplier interface {
|
||||||
|
ApplyStatus(ctx context.Context, status models.LoopStatus) (
|
||||||
|
outcome string, err error)
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,12 +14,6 @@ func (l *Loop) GetStatus() (status models.LoopStatus) {
|
|||||||
|
|
||||||
type StartData = state.StartData
|
type StartData = state.StartData
|
||||||
|
|
||||||
type StartStopper interface {
|
|
||||||
Start(ctx context.Context, data StartData) (
|
|
||||||
outcome string, err error)
|
|
||||||
Stop(ctx context.Context) (outcome string, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Loop) Start(ctx context.Context, data StartData) (
|
func (l *Loop) Start(ctx context.Context, data StartData) (
|
||||||
outcome string, err error) {
|
outcome string, err error) {
|
||||||
l.startMu.Lock()
|
l.startMu.Lock()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// Code generated by MockGen. DO NOT EDIT.
|
// Code generated by MockGen. DO NOT EDIT.
|
||||||
// Source: github.com/qdm12/gluetun/internal/provider/common (interfaces: ParallelResolver,Storage)
|
// Source: github.com/qdm12/gluetun/internal/provider/common (interfaces: ParallelResolver,Storage,Unzipper)
|
||||||
|
|
||||||
// Package common is a generated GoMock package.
|
// Package common is a generated GoMock package.
|
||||||
package common
|
package common
|
||||||
@@ -105,3 +105,41 @@ func (mr *MockStorageMockRecorder) GetServerByName(arg0, arg1 interface{}) *gomo
|
|||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetServerByName", reflect.TypeOf((*MockStorage)(nil).GetServerByName), arg0, arg1)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetServerByName", reflect.TypeOf((*MockStorage)(nil).GetServerByName), arg0, arg1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MockUnzipper is a mock of Unzipper interface.
|
||||||
|
type MockUnzipper struct {
|
||||||
|
ctrl *gomock.Controller
|
||||||
|
recorder *MockUnzipperMockRecorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockUnzipperMockRecorder is the mock recorder for MockUnzipper.
|
||||||
|
type MockUnzipperMockRecorder struct {
|
||||||
|
mock *MockUnzipper
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMockUnzipper creates a new mock instance.
|
||||||
|
func NewMockUnzipper(ctrl *gomock.Controller) *MockUnzipper {
|
||||||
|
mock := &MockUnzipper{ctrl: ctrl}
|
||||||
|
mock.recorder = &MockUnzipperMockRecorder{mock}
|
||||||
|
return mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||||
|
func (m *MockUnzipper) EXPECT() *MockUnzipperMockRecorder {
|
||||||
|
return m.recorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// FetchAndExtract mocks base method.
|
||||||
|
func (m *MockUnzipper) FetchAndExtract(arg0 context.Context, arg1 string) (map[string][]byte, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "FetchAndExtract", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(map[string][]byte)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// FetchAndExtract indicates an expected call of FetchAndExtract.
|
||||||
|
func (mr *MockUnzipperMockRecorder) FetchAndExtract(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchAndExtract", reflect.TypeOf((*MockUnzipper)(nil).FetchAndExtract), arg0, arg1)
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ package common
|
|||||||
|
|
||||||
// Exceptionally, these mocks are exported since they are used by all
|
// Exceptionally, these mocks are exported since they are used by all
|
||||||
// provider subpackages tests, and it reduces test code duplication a lot.
|
// provider subpackages tests, and it reduces test code duplication a lot.
|
||||||
//go:generate mockgen -destination=mocks.go -package $GOPACKAGE . ParallelResolver,Storage
|
//go:generate mockgen -destination=mocks.go -package $GOPACKAGE . ParallelResolver,Storage,Unzipper
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ type ParallelResolver interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Unzipper interface {
|
type Unzipper interface {
|
||||||
FetchAndExtract(ctx context.Context, url string) (contents map[string][]byte, err error)
|
FetchAndExtract(ctx context.Context, url string) (
|
||||||
|
contents map[string][]byte, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
type Warner interface {
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/constants"
|
"github.com/qdm12/gluetun/internal/constants"
|
||||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||||
"github.com/qdm12/gluetun/internal/models"
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
"github.com/qdm12/gluetun/internal/openvpn/extract"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -28,7 +27,7 @@ func (p *Provider) GetConnection(selection settings.ServerSelection) (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getOpenVPNConnection(extractor extract.Interface,
|
func getOpenVPNConnection(extractor extractor,
|
||||||
selection settings.ServerSelection) (
|
selection settings.ServerSelection) (
|
||||||
connection models.Connection, err error) {
|
connection models.Connection, err error) {
|
||||||
_, connection, err = extractor.Data(*selection.OpenVPN.ConfFile)
|
_, connection, err = extractor.Data(*selection.OpenVPN.ConfFile)
|
||||||
|
|||||||
8
internal/provider/custom/interfaces.go
Normal file
8
internal/provider/custom/interfaces.go
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package custom
|
||||||
|
|
||||||
|
import "github.com/qdm12/gluetun/internal/models"
|
||||||
|
|
||||||
|
type extractor interface {
|
||||||
|
Data(filepath string) (lines []string,
|
||||||
|
connection models.Connection, err error)
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Provider struct {
|
type Provider struct {
|
||||||
extractor extract.Interface
|
extractor extractor
|
||||||
utils.NoPortForwarder
|
utils.NoPortForwarder
|
||||||
common.Fetcher
|
common.Fetcher
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,20 +2,15 @@ package updater
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/qdm12/gluetun/internal/provider/common"
|
"github.com/qdm12/gluetun/internal/provider/common"
|
||||||
"github.com/qdm12/gluetun/internal/updater/unzip"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Updater struct {
|
type Updater struct {
|
||||||
unzipper unzip.Unzipper
|
unzipper common.Unzipper
|
||||||
presolver common.ParallelResolver
|
presolver common.ParallelResolver
|
||||||
warner Warner
|
warner common.Warner
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
func New(unzipper common.Unzipper, warner common.Warner) *Updater {
|
||||||
Warn(s string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(unzipper unzip.Unzipper, warner Warner) *Updater {
|
|
||||||
return &Updater{
|
return &Updater{
|
||||||
unzipper: unzipper,
|
unzipper: unzipper,
|
||||||
presolver: newParallelResolver(),
|
presolver: newParallelResolver(),
|
||||||
|
|||||||
@@ -2,20 +2,15 @@ package updater
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/qdm12/gluetun/internal/provider/common"
|
"github.com/qdm12/gluetun/internal/provider/common"
|
||||||
"github.com/qdm12/gluetun/internal/updater/unzip"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Updater struct {
|
type Updater struct {
|
||||||
unzipper unzip.Unzipper
|
unzipper common.Unzipper
|
||||||
presolver common.ParallelResolver
|
presolver common.ParallelResolver
|
||||||
warner Warner
|
warner common.Warner
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
func New(unzipper common.Unzipper, warner common.Warner) *Updater {
|
||||||
Warn(s string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(unzipper unzip.Unzipper, warner Warner) *Updater {
|
|
||||||
return &Updater{
|
return &Updater{
|
||||||
unzipper: unzipper,
|
unzipper: unzipper,
|
||||||
presolver: newParallelResolver(),
|
presolver: newParallelResolver(),
|
||||||
|
|||||||
@@ -9,14 +9,10 @@ import (
|
|||||||
type Updater struct {
|
type Updater struct {
|
||||||
client *http.Client
|
client *http.Client
|
||||||
presolver common.ParallelResolver
|
presolver common.ParallelResolver
|
||||||
warner Warner
|
warner common.Warner
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
func New(client *http.Client, warner common.Warner) *Updater {
|
||||||
Warn(s string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(client *http.Client, warner Warner) *Updater {
|
|
||||||
return &Updater{
|
return &Updater{
|
||||||
client: client,
|
client: client,
|
||||||
presolver: newParallelResolver(),
|
presolver: newParallelResolver(),
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||||
"github.com/qdm12/gluetun/internal/models"
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
"github.com/qdm12/gluetun/internal/provider/common"
|
"github.com/qdm12/gluetun/internal/provider/common"
|
||||||
"github.com/qdm12/gluetun/internal/updater/unzip/mock_unzip"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
@@ -22,7 +21,7 @@ func Test_Updater_GetServers(t *testing.T) {
|
|||||||
minServers int
|
minServers int
|
||||||
|
|
||||||
// Mocks
|
// Mocks
|
||||||
warnerBuilder func(ctrl *gomock.Controller) Warner
|
warnerBuilder func(ctrl *gomock.Controller) common.Warner
|
||||||
|
|
||||||
// Unzip
|
// Unzip
|
||||||
unzipContents map[string][]byte
|
unzipContents map[string][]byte
|
||||||
@@ -40,25 +39,25 @@ func Test_Updater_GetServers(t *testing.T) {
|
|||||||
err error
|
err error
|
||||||
}{
|
}{
|
||||||
"unzipper error": {
|
"unzipper error": {
|
||||||
warnerBuilder: func(ctrl *gomock.Controller) Warner { return nil },
|
warnerBuilder: func(ctrl *gomock.Controller) common.Warner { return nil },
|
||||||
unzipErr: errors.New("dummy"),
|
unzipErr: errors.New("dummy"),
|
||||||
err: errors.New("dummy"),
|
err: errors.New("dummy"),
|
||||||
},
|
},
|
||||||
"not enough unzip contents": {
|
"not enough unzip contents": {
|
||||||
minServers: 1,
|
minServers: 1,
|
||||||
warnerBuilder: func(ctrl *gomock.Controller) Warner { return nil },
|
warnerBuilder: func(ctrl *gomock.Controller) common.Warner { return nil },
|
||||||
unzipContents: map[string][]byte{},
|
unzipContents: map[string][]byte{},
|
||||||
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
||||||
},
|
},
|
||||||
"no openvpn file": {
|
"no openvpn file": {
|
||||||
minServers: 1,
|
minServers: 1,
|
||||||
warnerBuilder: func(ctrl *gomock.Controller) Warner { return nil },
|
warnerBuilder: func(ctrl *gomock.Controller) common.Warner { return nil },
|
||||||
unzipContents: map[string][]byte{"somefile.txt": {}},
|
unzipContents: map[string][]byte{"somefile.txt": {}},
|
||||||
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
||||||
},
|
},
|
||||||
"invalid proto": {
|
"invalid proto": {
|
||||||
minServers: 1,
|
minServers: 1,
|
||||||
warnerBuilder: func(ctrl *gomock.Controller) Warner {
|
warnerBuilder: func(ctrl *gomock.Controller) common.Warner {
|
||||||
warner := NewMockWarner(ctrl)
|
warner := NewMockWarner(ctrl)
|
||||||
warner.EXPECT().Warn("unknown protocol: invalid in badproto.ovpn")
|
warner.EXPECT().Warn("unknown protocol: invalid in badproto.ovpn")
|
||||||
return warner
|
return warner
|
||||||
@@ -68,7 +67,7 @@ func Test_Updater_GetServers(t *testing.T) {
|
|||||||
},
|
},
|
||||||
"no host": {
|
"no host": {
|
||||||
minServers: 1,
|
minServers: 1,
|
||||||
warnerBuilder: func(ctrl *gomock.Controller) Warner {
|
warnerBuilder: func(ctrl *gomock.Controller) common.Warner {
|
||||||
warner := NewMockWarner(ctrl)
|
warner := NewMockWarner(ctrl)
|
||||||
warner.EXPECT().Warn("remote host not found in nohost.ovpn")
|
warner.EXPECT().Warn("remote host not found in nohost.ovpn")
|
||||||
return warner
|
return warner
|
||||||
@@ -78,7 +77,7 @@ func Test_Updater_GetServers(t *testing.T) {
|
|||||||
},
|
},
|
||||||
"multiple hosts": {
|
"multiple hosts": {
|
||||||
minServers: 1,
|
minServers: 1,
|
||||||
warnerBuilder: func(ctrl *gomock.Controller) Warner {
|
warnerBuilder: func(ctrl *gomock.Controller) common.Warner {
|
||||||
warner := NewMockWarner(ctrl)
|
warner := NewMockWarner(ctrl)
|
||||||
warner.EXPECT().Warn("only using the first host \"hosta\" and discarding 1 other hosts")
|
warner.EXPECT().Warn("only using the first host \"hosta\" and discarding 1 other hosts")
|
||||||
return warner
|
return warner
|
||||||
@@ -91,7 +90,7 @@ func Test_Updater_GetServers(t *testing.T) {
|
|||||||
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
||||||
},
|
},
|
||||||
"resolve error": {
|
"resolve error": {
|
||||||
warnerBuilder: func(ctrl *gomock.Controller) Warner {
|
warnerBuilder: func(ctrl *gomock.Controller) common.Warner {
|
||||||
warner := NewMockWarner(ctrl)
|
warner := NewMockWarner(ctrl)
|
||||||
warner.EXPECT().Warn("resolve warning")
|
warner.EXPECT().Warn("resolve warning")
|
||||||
return warner
|
return warner
|
||||||
@@ -107,7 +106,7 @@ func Test_Updater_GetServers(t *testing.T) {
|
|||||||
},
|
},
|
||||||
"filename parsing error": {
|
"filename parsing error": {
|
||||||
minServers: 1,
|
minServers: 1,
|
||||||
warnerBuilder: func(ctrl *gomock.Controller) Warner {
|
warnerBuilder: func(ctrl *gomock.Controller) common.Warner {
|
||||||
warner := NewMockWarner(ctrl)
|
warner := NewMockWarner(ctrl)
|
||||||
warner.EXPECT().Warn("country code is unknown: unknown in ipvanish-unknown-City-A-hosta.ovpn")
|
warner.EXPECT().Warn("country code is unknown: unknown in ipvanish-unknown-City-A-hosta.ovpn")
|
||||||
return warner
|
return warner
|
||||||
@@ -119,7 +118,7 @@ func Test_Updater_GetServers(t *testing.T) {
|
|||||||
},
|
},
|
||||||
"success": {
|
"success": {
|
||||||
minServers: 1,
|
minServers: 1,
|
||||||
warnerBuilder: func(ctrl *gomock.Controller) Warner {
|
warnerBuilder: func(ctrl *gomock.Controller) common.Warner {
|
||||||
warner := NewMockWarner(ctrl)
|
warner := NewMockWarner(ctrl)
|
||||||
warner.EXPECT().Warn("resolve warning")
|
warner.EXPECT().Warn("resolve warning")
|
||||||
return warner
|
return warner
|
||||||
@@ -163,7 +162,7 @@ func Test_Updater_GetServers(t *testing.T) {
|
|||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
unzipper := mock_unzip.NewMockUnzipper(ctrl)
|
unzipper := common.NewMockUnzipper(ctrl)
|
||||||
const zipURL = "https://www.ipvanish.com/software/configs/configs.zip"
|
const zipURL = "https://www.ipvanish.com/software/configs/configs.zip"
|
||||||
unzipper.EXPECT().FetchAndExtract(ctx, zipURL).
|
unzipper.EXPECT().FetchAndExtract(ctx, zipURL).
|
||||||
Return(testCase.unzipContents, testCase.unzipErr)
|
Return(testCase.unzipContents, testCase.unzipErr)
|
||||||
|
|||||||
@@ -2,20 +2,15 @@ package updater
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/qdm12/gluetun/internal/provider/common"
|
"github.com/qdm12/gluetun/internal/provider/common"
|
||||||
"github.com/qdm12/gluetun/internal/updater/unzip"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Updater struct {
|
type Updater struct {
|
||||||
unzipper unzip.Unzipper
|
unzipper common.Unzipper
|
||||||
warner Warner
|
warner common.Warner
|
||||||
presolver common.ParallelResolver
|
presolver common.ParallelResolver
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
func New(unzipper common.Unzipper, warner common.Warner) *Updater {
|
||||||
Warn(s string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(unzipper unzip.Unzipper, warner Warner) *Updater {
|
|
||||||
return &Updater{
|
return &Updater{
|
||||||
unzipper: unzipper,
|
unzipper: unzipper,
|
||||||
warner: warner,
|
warner: warner,
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ func Test_Updater_GetServers(t *testing.T) {
|
|||||||
minServers int
|
minServers int
|
||||||
|
|
||||||
// Mocks
|
// Mocks
|
||||||
warnerBuilder func(ctrl *gomock.Controller) Warner
|
warnerBuilder func(ctrl *gomock.Controller) common.Warner
|
||||||
|
|
||||||
// From API
|
// From API
|
||||||
responseBody string
|
responseBody string
|
||||||
@@ -43,12 +43,12 @@ func Test_Updater_GetServers(t *testing.T) {
|
|||||||
err error
|
err error
|
||||||
}{
|
}{
|
||||||
"http response error": {
|
"http response error": {
|
||||||
warnerBuilder: func(ctrl *gomock.Controller) Warner { return nil },
|
warnerBuilder: func(ctrl *gomock.Controller) common.Warner { return nil },
|
||||||
responseStatus: http.StatusNoContent,
|
responseStatus: http.StatusNoContent,
|
||||||
err: errors.New("failed fetching API: HTTP status code not OK: 204 No Content"),
|
err: errors.New("failed fetching API: HTTP status code not OK: 204 No Content"),
|
||||||
},
|
},
|
||||||
"resolve error": {
|
"resolve error": {
|
||||||
warnerBuilder: func(ctrl *gomock.Controller) Warner {
|
warnerBuilder: func(ctrl *gomock.Controller) common.Warner {
|
||||||
warner := NewMockWarner(ctrl)
|
warner := NewMockWarner(ctrl)
|
||||||
warner.EXPECT().Warn("resolve warning")
|
warner.EXPECT().Warn("resolve warning")
|
||||||
return warner
|
return warner
|
||||||
@@ -65,7 +65,7 @@ func Test_Updater_GetServers(t *testing.T) {
|
|||||||
},
|
},
|
||||||
"not enough servers": {
|
"not enough servers": {
|
||||||
minServers: 2,
|
minServers: 2,
|
||||||
warnerBuilder: func(ctrl *gomock.Controller) Warner { return nil },
|
warnerBuilder: func(ctrl *gomock.Controller) common.Warner { return nil },
|
||||||
responseBody: `{"servers":[
|
responseBody: `{"servers":[
|
||||||
{"hostnames":{"openvpn":"hosta"}}
|
{"hostnames":{"openvpn":"hosta"}}
|
||||||
]}`,
|
]}`,
|
||||||
@@ -74,7 +74,7 @@ func Test_Updater_GetServers(t *testing.T) {
|
|||||||
},
|
},
|
||||||
"success": {
|
"success": {
|
||||||
minServers: 1,
|
minServers: 1,
|
||||||
warnerBuilder: func(ctrl *gomock.Controller) Warner {
|
warnerBuilder: func(ctrl *gomock.Controller) common.Warner {
|
||||||
warner := NewMockWarner(ctrl)
|
warner := NewMockWarner(ctrl)
|
||||||
warner.EXPECT().Warn("resolve warning")
|
warner.EXPECT().Warn("resolve warning")
|
||||||
return warner
|
return warner
|
||||||
|
|||||||
@@ -9,14 +9,10 @@ import (
|
|||||||
type Updater struct {
|
type Updater struct {
|
||||||
client *http.Client
|
client *http.Client
|
||||||
presolver common.ParallelResolver
|
presolver common.ParallelResolver
|
||||||
warner Warner
|
warner common.Warner
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
func New(client *http.Client, warner common.Warner) *Updater {
|
||||||
Warn(s string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(client *http.Client, warner Warner) *Updater {
|
|
||||||
return &Updater{
|
return &Updater{
|
||||||
client: client,
|
client: client,
|
||||||
presolver: newParallelResolver(),
|
presolver: newParallelResolver(),
|
||||||
|
|||||||
@@ -2,18 +2,16 @@ package updater
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/qdm12/gluetun/internal/provider/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Updater struct {
|
type Updater struct {
|
||||||
client *http.Client
|
client *http.Client
|
||||||
warner Warner
|
warner common.Warner
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
func New(client *http.Client, warner common.Warner) *Updater {
|
||||||
Warn(message string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(client *http.Client, warner Warner) *Updater {
|
|
||||||
return &Updater{
|
return &Updater{
|
||||||
client: client,
|
client: client,
|
||||||
warner: warner,
|
warner: warner,
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
package updater
|
package updater
|
||||||
|
|
||||||
import "github.com/qdm12/gluetun/internal/updater/unzip"
|
import (
|
||||||
|
"github.com/qdm12/gluetun/internal/provider/common"
|
||||||
|
)
|
||||||
|
|
||||||
type Updater struct {
|
type Updater struct {
|
||||||
unzipper unzip.Unzipper
|
unzipper common.Unzipper
|
||||||
warner Warner
|
warner common.Warner
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
func New(unzipper common.Unzipper, warner common.Warner) *Updater {
|
||||||
Warn(s string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(unzipper unzip.Unzipper, warner Warner) *Updater {
|
|
||||||
return &Updater{
|
return &Updater{
|
||||||
unzipper: unzipper,
|
unzipper: unzipper,
|
||||||
warner: warner,
|
warner: warner,
|
||||||
|
|||||||
@@ -4,22 +4,17 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/provider/common"
|
"github.com/qdm12/gluetun/internal/provider/common"
|
||||||
"github.com/qdm12/gluetun/internal/updater/unzip"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Updater struct {
|
type Updater struct {
|
||||||
client *http.Client
|
client *http.Client
|
||||||
unzipper unzip.Unzipper
|
unzipper common.Unzipper
|
||||||
presolver common.ParallelResolver
|
presolver common.ParallelResolver
|
||||||
warner Warner
|
warner common.Warner
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
func New(client *http.Client, unzipper common.Unzipper,
|
||||||
Warn(s string)
|
warner common.Warner) *Updater {
|
||||||
}
|
|
||||||
|
|
||||||
func New(client *http.Client, unzipper unzip.Unzipper,
|
|
||||||
warner Warner) *Updater {
|
|
||||||
return &Updater{
|
return &Updater{
|
||||||
client: client,
|
client: client,
|
||||||
unzipper: unzipper,
|
unzipper: unzipper,
|
||||||
|
|||||||
@@ -8,10 +8,6 @@ type Updater struct {
|
|||||||
client *http.Client
|
client *http.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
|
||||||
Warn(s string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(client *http.Client) *Updater {
|
func New(client *http.Client) *Updater {
|
||||||
return &Updater{
|
return &Updater{
|
||||||
client: client,
|
client: client,
|
||||||
|
|||||||
@@ -2,20 +2,15 @@ package updater
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/qdm12/gluetun/internal/provider/common"
|
"github.com/qdm12/gluetun/internal/provider/common"
|
||||||
"github.com/qdm12/gluetun/internal/updater/unzip"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Updater struct {
|
type Updater struct {
|
||||||
unzipper unzip.Unzipper
|
unzipper common.Unzipper
|
||||||
presolver common.ParallelResolver
|
presolver common.ParallelResolver
|
||||||
warner Warner
|
warner common.Warner
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
func New(unzipper common.Unzipper, warner common.Warner) *Updater {
|
||||||
Warn(s string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(unzipper unzip.Unzipper, warner Warner) *Updater {
|
|
||||||
return &Updater{
|
return &Updater{
|
||||||
unzipper: unzipper,
|
unzipper: unzipper,
|
||||||
presolver: newParallelResolver(),
|
presolver: newParallelResolver(),
|
||||||
|
|||||||
@@ -2,18 +2,16 @@ package updater
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/qdm12/gluetun/internal/provider/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Updater struct {
|
type Updater struct {
|
||||||
client *http.Client
|
client *http.Client
|
||||||
warner Warner
|
warner common.Warner
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
func New(client *http.Client, warner common.Warner) *Updater {
|
||||||
Warn(s string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(client *http.Client, warner Warner) *Updater {
|
|
||||||
return &Updater{
|
return &Updater{
|
||||||
client: client,
|
client: client,
|
||||||
warner: warner,
|
warner: warner,
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ func NewProviders(storage Storage, timeNow func() time.Time,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Providers) Get(providerName string) (provider Provider) {
|
func (p *Providers) Get(providerName string) (provider Provider) { //nolint:ireturn
|
||||||
provider, ok := p.providerNameToProvider[providerName]
|
provider, ok := p.providerNameToProvider[providerName]
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(fmt.Sprintf("provider %q not found", providerName))
|
panic(fmt.Sprintf("provider %q not found", providerName))
|
||||||
|
|||||||
@@ -4,22 +4,17 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/provider/common"
|
"github.com/qdm12/gluetun/internal/provider/common"
|
||||||
"github.com/qdm12/gluetun/internal/updater/unzip"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Updater struct {
|
type Updater struct {
|
||||||
client *http.Client
|
client *http.Client
|
||||||
unzipper unzip.Unzipper
|
unzipper common.Unzipper
|
||||||
presolver common.ParallelResolver
|
presolver common.ParallelResolver
|
||||||
warner Warner
|
warner common.Warner
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
func New(client *http.Client, unzipper common.Unzipper,
|
||||||
Warn(s string)
|
warner common.Warner) *Updater {
|
||||||
}
|
|
||||||
|
|
||||||
func New(client *http.Client, unzipper unzip.Unzipper,
|
|
||||||
warner Warner) *Updater {
|
|
||||||
return &Updater{
|
return &Updater{
|
||||||
client: client,
|
client: client,
|
||||||
unzipper: unzipper,
|
unzipper: unzipper,
|
||||||
|
|||||||
@@ -4,22 +4,17 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/provider/common"
|
"github.com/qdm12/gluetun/internal/provider/common"
|
||||||
"github.com/qdm12/gluetun/internal/updater/unzip"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Updater struct {
|
type Updater struct {
|
||||||
client *http.Client
|
client *http.Client
|
||||||
unzipper unzip.Unzipper
|
unzipper common.Unzipper
|
||||||
presolver common.ParallelResolver
|
presolver common.ParallelResolver
|
||||||
warner Warner
|
warner common.Warner
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
func New(client *http.Client, unzipper common.Unzipper,
|
||||||
Warn(s string)
|
warner common.Warner) *Updater {
|
||||||
}
|
|
||||||
|
|
||||||
func New(client *http.Client, unzipper unzip.Unzipper,
|
|
||||||
warner Warner) *Updater {
|
|
||||||
return &Updater{
|
return &Updater{
|
||||||
client: client,
|
client: client,
|
||||||
unzipper: unzipper,
|
unzipper: unzipper,
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/qdm12/gluetun/internal/provider/common"
|
||||||
"github.com/qdm12/gluetun/internal/provider/surfshark/servers"
|
"github.com/qdm12/gluetun/internal/provider/surfshark/servers"
|
||||||
"github.com/qdm12/gluetun/internal/updater/openvpn"
|
"github.com/qdm12/gluetun/internal/updater/openvpn"
|
||||||
"github.com/qdm12/gluetun/internal/updater/unzip"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func addOpenVPNServersFromZip(ctx context.Context,
|
func addOpenVPNServersFromZip(ctx context.Context,
|
||||||
unzipper unzip.Unzipper, hts hostToServer) (
|
unzipper common.Unzipper, hts hostToServer) (
|
||||||
warnings []string, err error) {
|
warnings []string, err error) {
|
||||||
const url = "https://my.surfshark.com/vpn/api/v1/server/configurations"
|
const url = "https://my.surfshark.com/vpn/api/v1/server/configurations"
|
||||||
contents, err := unzipper.FetchAndExtract(ctx, url)
|
contents, err := unzipper.FetchAndExtract(ctx, url)
|
||||||
|
|||||||
@@ -2,20 +2,15 @@ package updater
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/qdm12/gluetun/internal/provider/common"
|
"github.com/qdm12/gluetun/internal/provider/common"
|
||||||
"github.com/qdm12/gluetun/internal/updater/unzip"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Updater struct {
|
type Updater struct {
|
||||||
unzipper unzip.Unzipper
|
unzipper common.Unzipper
|
||||||
presolver common.ParallelResolver
|
presolver common.ParallelResolver
|
||||||
warner Warner
|
warner common.Warner
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
func New(unzipper common.Unzipper, warner common.Warner) *Updater {
|
||||||
Warn(s string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(unzipper unzip.Unzipper, warner Warner) *Updater {
|
|
||||||
return &Updater{
|
return &Updater{
|
||||||
unzipper: unzipper,
|
unzipper: unzipper,
|
||||||
presolver: newParallelResolver(),
|
presolver: newParallelResolver(),
|
||||||
|
|||||||
@@ -2,20 +2,15 @@ package updater
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/qdm12/gluetun/internal/provider/common"
|
"github.com/qdm12/gluetun/internal/provider/common"
|
||||||
"github.com/qdm12/gluetun/internal/updater/unzip"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Updater struct {
|
type Updater struct {
|
||||||
unzipper unzip.Unzipper
|
unzipper common.Unzipper
|
||||||
presolver common.ParallelResolver
|
presolver common.ParallelResolver
|
||||||
warner Warner
|
warner common.Warner
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
func New(unzipper common.Unzipper, warner common.Warner) *Updater {
|
||||||
Warn(s string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(unzipper unzip.Unzipper, warner Warner) *Updater {
|
|
||||||
return &Updater{
|
return &Updater{
|
||||||
unzipper: unzipper,
|
unzipper: unzipper,
|
||||||
presolver: newParallelResolver(),
|
presolver: newParallelResolver(),
|
||||||
|
|||||||
@@ -2,20 +2,15 @@ package updater
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/qdm12/gluetun/internal/provider/common"
|
"github.com/qdm12/gluetun/internal/provider/common"
|
||||||
"github.com/qdm12/gluetun/internal/updater/unzip"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Updater struct {
|
type Updater struct {
|
||||||
unzipper unzip.Unzipper
|
unzipper common.Unzipper
|
||||||
presolver common.ParallelResolver
|
presolver common.ParallelResolver
|
||||||
warner Warner
|
warner common.Warner
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
func New(unzipper common.Unzipper, warner common.Warner) *Updater {
|
||||||
Warn(s string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(unzipper unzip.Unzipper, warner Warner) *Updater {
|
|
||||||
return &Updater{
|
return &Updater{
|
||||||
unzipper: unzipper,
|
unzipper: unzipper,
|
||||||
presolver: newParallelResolver(),
|
presolver: newParallelResolver(),
|
||||||
|
|||||||
@@ -4,14 +4,10 @@ import "github.com/qdm12/gluetun/internal/provider/common"
|
|||||||
|
|
||||||
type Updater struct {
|
type Updater struct {
|
||||||
presolver common.ParallelResolver
|
presolver common.ParallelResolver
|
||||||
warner Warner
|
warner common.Warner
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
func New(warner common.Warner) *Updater {
|
||||||
Warn(s string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(warner Warner) *Updater {
|
|
||||||
return &Updater{
|
return &Updater{
|
||||||
presolver: newParallelResolver(),
|
presolver: newParallelResolver(),
|
||||||
warner: warner,
|
warner: warner,
|
||||||
|
|||||||
@@ -2,18 +2,16 @@ package updater
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/qdm12/gluetun/internal/provider/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Updater struct {
|
type Updater struct {
|
||||||
client *http.Client
|
client *http.Client
|
||||||
warner Warner
|
warner common.Warner
|
||||||
}
|
}
|
||||||
|
|
||||||
type Warner interface {
|
func New(client *http.Client, warner common.Warner) *Updater {
|
||||||
Warn(s string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(client *http.Client, warner Warner) *Updater {
|
|
||||||
return &Updater{
|
return &Updater{
|
||||||
client: client,
|
client: client,
|
||||||
warner: warner,
|
warner: warner,
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
package publicip
|
|
||||||
|
|
||||||
import "github.com/qdm12/gluetun/internal/publicip/state"
|
|
||||||
|
|
||||||
type GetSetter = state.DataGetSetter
|
|
||||||
type SettingsGetSetter = state.SettingsGetSetter
|
|
||||||
@@ -12,12 +12,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Fetcher = (*Fetch)(nil)
|
|
||||||
|
|
||||||
type Fetcher interface {
|
|
||||||
FetchPublicIP(ctx context.Context) (ip net.IP, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Fetch struct {
|
type Fetch struct {
|
||||||
client *http.Client
|
client *http.Client
|
||||||
randIntn func(n int) int
|
randIntn func(n int) int
|
||||||
|
|||||||
28
internal/publicip/interfaces.go
Normal file
28
internal/publicip/interfaces.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package publicip
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
|
publicipmodels "github.com/qdm12/gluetun/internal/publicip/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type statusManager interface {
|
||||||
|
GetStatus() (status models.LoopStatus)
|
||||||
|
SetStatus(status models.LoopStatus)
|
||||||
|
ApplyStatus(ctx context.Context, status models.LoopStatus) (
|
||||||
|
outcome string, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type stateManager interface {
|
||||||
|
GetData() (data publicipmodels.IPInfoData)
|
||||||
|
SetData(data publicipmodels.IPInfoData)
|
||||||
|
GetSettings() (settings settings.PublicIP)
|
||||||
|
SetSettings(ctx context.Context, settings settings.PublicIP) (outcome string)
|
||||||
|
}
|
||||||
|
|
||||||
|
type fetcher interface {
|
||||||
|
FetchPublicIP(ctx context.Context) (ip net.IP, err error)
|
||||||
|
}
|
||||||
@@ -11,22 +11,11 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/publicip/state"
|
"github.com/qdm12/gluetun/internal/publicip/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Looper = (*Loop)(nil)
|
|
||||||
|
|
||||||
type Looper interface {
|
|
||||||
Runner
|
|
||||||
RestartTickerRunner
|
|
||||||
loopstate.Getter
|
|
||||||
loopstate.Applier
|
|
||||||
SettingsGetSetter
|
|
||||||
GetSetter
|
|
||||||
}
|
|
||||||
|
|
||||||
type Loop struct {
|
type Loop struct {
|
||||||
statusManager loopstate.Manager
|
statusManager statusManager
|
||||||
state state.Manager
|
state stateManager
|
||||||
// Objects
|
// Objects
|
||||||
fetcher Fetcher
|
fetcher fetcher
|
||||||
client *http.Client
|
client *http.Client
|
||||||
logger Logger
|
logger Logger
|
||||||
// Fixed settings
|
// Fixed settings
|
||||||
|
|||||||
@@ -8,10 +8,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/constants"
|
"github.com/qdm12/gluetun/internal/constants"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Runner interface {
|
|
||||||
Run(ctx context.Context, done chan<- struct{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
|
func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/publicip/models"
|
"github.com/qdm12/gluetun/internal/publicip/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DataGetSetter interface {
|
|
||||||
GetData() (data models.IPInfoData)
|
|
||||||
SetData(data models.IPInfoData)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *State) GetData() (data models.IPInfoData) {
|
func (s *State) GetData() (data models.IPInfoData) {
|
||||||
s.ipDataMu.RLock()
|
s.ipDataMu.RLock()
|
||||||
defer s.ipDataMu.RUnlock()
|
defer s.ipDataMu.RUnlock()
|
||||||
|
|||||||
@@ -7,12 +7,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SettingsGetSetter interface {
|
|
||||||
GetSettings() (settings settings.PublicIP)
|
|
||||||
SetSettings(ctx context.Context,
|
|
||||||
settings settings.PublicIP) (outcome string)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *State) GetSettings() (settings settings.PublicIP) {
|
func (s *State) GetSettings() (settings settings.PublicIP) {
|
||||||
s.settingsMu.RLock()
|
s.settingsMu.RLock()
|
||||||
defer s.settingsMu.RUnlock()
|
defer s.settingsMu.RUnlock()
|
||||||
|
|||||||
@@ -1,21 +1,15 @@
|
|||||||
package state
|
package state
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||||
"github.com/qdm12/gluetun/internal/loopstate"
|
"github.com/qdm12/gluetun/internal/models"
|
||||||
"github.com/qdm12/gluetun/internal/publicip/models"
|
publicipmodels "github.com/qdm12/gluetun/internal/publicip/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Manager = (*State)(nil)
|
func New(statusApplier StatusApplier,
|
||||||
|
|
||||||
type Manager interface {
|
|
||||||
SettingsGetSetter
|
|
||||||
DataGetSetter
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(statusApplier loopstate.Applier,
|
|
||||||
settings settings.PublicIP,
|
settings settings.PublicIP,
|
||||||
updateTicker chan<- struct{}) *State {
|
updateTicker chan<- struct{}) *State {
|
||||||
return &State{
|
return &State{
|
||||||
@@ -26,13 +20,18 @@ func New(statusApplier loopstate.Applier,
|
|||||||
}
|
}
|
||||||
|
|
||||||
type State struct {
|
type State struct {
|
||||||
statusApplier loopstate.Applier
|
statusApplier StatusApplier
|
||||||
|
|
||||||
settings settings.PublicIP
|
settings settings.PublicIP
|
||||||
settingsMu sync.RWMutex
|
settingsMu sync.RWMutex
|
||||||
|
|
||||||
ipData models.IPInfoData
|
ipData publicipmodels.IPInfoData
|
||||||
ipDataMu sync.RWMutex
|
ipDataMu sync.RWMutex
|
||||||
|
|
||||||
updateTicker chan<- struct{}
|
updateTicker chan<- struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type StatusApplier interface {
|
||||||
|
ApplyStatus(ctx context.Context, status models.LoopStatus) (
|
||||||
|
outcome string, err error)
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,10 +7,6 @@ import (
|
|||||||
"github.com/qdm12/gluetun/internal/constants"
|
"github.com/qdm12/gluetun/internal/constants"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RestartTickerRunner interface {
|
|
||||||
RunRestartTicker(ctx context.Context, done chan<- struct{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Loop) RunRestartTicker(ctx context.Context, done chan<- struct{}) {
|
func (l *Loop) RunRestartTicker(ctx context.Context, done chan<- struct{}) {
|
||||||
defer close(done)
|
defer close(done)
|
||||||
timer := time.NewTimer(time.Hour)
|
timer := time.NewTimer(time.Hour)
|
||||||
@@ -30,7 +26,7 @@ func (l *Loop) RunRestartTicker(ctx context.Context, done chan<- struct{}) {
|
|||||||
return
|
return
|
||||||
case <-timer.C:
|
case <-timer.C:
|
||||||
lastTick = l.timeNow()
|
lastTick = l.timeNow()
|
||||||
_, _ = l.ApplyStatus(ctx, constants.Running)
|
_, _ = l.statusManager.ApplyStatus(ctx, constants.Running)
|
||||||
timer.Reset(*l.state.GetSettings().Period)
|
timer.Reset(*l.state.GetSettings().Period)
|
||||||
case <-l.updateTicker:
|
case <-l.updateTicker:
|
||||||
if !timerIsStopped && !timer.Stop() {
|
if !timerIsStopped && !timer.Stop() {
|
||||||
|
|||||||
@@ -12,10 +12,6 @@ var (
|
|||||||
ErrRouteDefaultNotFound = errors.New("default route not found")
|
ErrRouteDefaultNotFound = errors.New("default route not found")
|
||||||
)
|
)
|
||||||
|
|
||||||
type DefaultRouteGetter interface {
|
|
||||||
DefaultRoutes() (defaultRoutes []DefaultRoute, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type DefaultRoute struct {
|
type DefaultRoute struct {
|
||||||
NetInterface string
|
NetInterface string
|
||||||
Gateway net.IP
|
Gateway net.IP
|
||||||
|
|||||||
@@ -4,10 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Setuper interface {
|
|
||||||
Setup() (err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Routing) Setup() (err error) {
|
func (r *Routing) Setup() (err error) {
|
||||||
defaultRoutes, err := r.DefaultRoutes()
|
defaultRoutes, err := r.DefaultRoutes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -40,10 +36,6 @@ func (r *Routing) Setup() (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type TearDowner interface {
|
|
||||||
TearDown() error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Routing) TearDown() error {
|
func (r *Routing) TearDown() error {
|
||||||
defaultRoutes, err := r.DefaultRoutes()
|
defaultRoutes, err := r.DefaultRoutes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -20,10 +20,6 @@ type LocalNetwork struct {
|
|||||||
IP net.IP
|
IP net.IP
|
||||||
}
|
}
|
||||||
|
|
||||||
type LocalNetworksGetter interface {
|
|
||||||
LocalNetworks() (localNetworks []LocalNetwork, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Routing) LocalNetworks() (localNetworks []LocalNetwork, err error) {
|
func (r *Routing) LocalNetworks() (localNetworks []LocalNetwork, err error) {
|
||||||
links, err := r.netLinker.LinkList()
|
links, err := r.netLinker.LinkList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
3
internal/routing/mocks_generate_test.go
Normal file
3
internal/routing/mocks_generate_test.go
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
package routing
|
||||||
|
|
||||||
|
//go:generate mockgen -destination=mocks_test.go -package=$GOPACKAGE . NetLinker
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
// Code generated by MockGen. DO NOT EDIT.
|
// Code generated by MockGen. DO NOT EDIT.
|
||||||
// Source: github.com/qdm12/gluetun/internal/netlink (interfaces: NetLinker)
|
// Source: github.com/qdm12/gluetun/internal/routing (interfaces: NetLinker)
|
||||||
|
|
||||||
// Package mock_netlink is a generated GoMock package.
|
// Package routing is a generated GoMock package.
|
||||||
package mock_netlink
|
package routing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
@@ -12,10 +12,6 @@ const (
|
|||||||
outboundPriority = 99
|
outboundPriority = 99
|
||||||
)
|
)
|
||||||
|
|
||||||
type OutboundRoutesSetter interface {
|
|
||||||
SetOutboundRoutes(outboundSubnets []net.IPNet) error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Routing) SetOutboundRoutes(outboundSubnets []net.IPNet) error {
|
func (r *Routing) SetOutboundRoutes(outboundSubnets []net.IPNet) error {
|
||||||
defaultRoutes, err := r.DefaultRoutes()
|
defaultRoutes, err := r.DefaultRoutes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user