diff --git a/cmd/gluetun/main.go b/cmd/gluetun/main.go index ad3792a6..72043838 100644 --- a/cmd/gluetun/main.go +++ b/cmd/gluetun/main.go @@ -135,8 +135,16 @@ func _main(ctx context.Context, buildInfo models.BuildInformation, } } + // TODO run this in a loop or in openvpn to reload from file without restarting + storageLogger := logger.NewChild(logging.Settings{Prefix: "storage: "}) + storage, err := storage.New(storageLogger, constants.ServersData) + if err != nil { + return err + } + allServers := storage.GetServers() + var allSettings configuration.Settings - err := allSettings.Read(env, + err = allSettings.Read(env, allServers, logger.NewChild(logging.Settings{Prefix: "configuration: "})) if err != nil { return err @@ -200,15 +208,6 @@ func _main(ctx context.Context, buildInfo models.BuildInformation, return err } - // TODO run this in a loop or in openvpn to reload from file without restarting - storage := storage.New( - logger.NewChild(logging.Settings{Prefix: "storage: "}), - constants.ServersData) - allServers, err := storage.SyncServers(constants.GetAllServers()) - if err != nil { - return err - } - const defaultUsername = "nonrootuser" nonRootUsername, err := alpineConf.CreateUser(defaultUsername, puid) if err != nil { diff --git a/internal/cli/openvpnconfig.go b/internal/cli/openvpnconfig.go index de2d1f59..1ccdeaf5 100644 --- a/internal/cli/openvpnconfig.go +++ b/internal/cli/openvpnconfig.go @@ -18,13 +18,14 @@ type OpenvpnConfigMaker interface { } func (c *CLI) OpenvpnConfig(logger logging.Logger, env params.Interface) error { - var allSettings configuration.Settings - err := allSettings.Read(env, logger) + storage, err := storage.New(logger, constants.ServersData) if err != nil { return err } - allServers, err := storage.New(logger, constants.ServersData). - SyncServers(constants.GetAllServers()) + allServers := storage.GetServers() + + var allSettings configuration.Settings + err = allSettings.Read(env, allServers, logger) if err != nil { return err } diff --git a/internal/cli/update.go b/internal/cli/update.go index 8eaa5156..d7d6aafa 100644 --- a/internal/cli/update.go +++ b/internal/cli/update.go @@ -20,7 +20,7 @@ import ( var ( ErrModeUnspecified = errors.New("at least one of -enduser or -maintainers must be specified") - ErrSyncServers = errors.New("cannot sync hardcoded and persisted servers") + ErrNewStorage = errors.New("cannot create storage") ErrUpdateServerInformation = errors.New("cannot update server information") ErrWriteToFile = errors.New("cannot write updated information to file") ) @@ -68,11 +68,13 @@ func (c *CLI) Update(ctx context.Context, args []string, logger logging.Logger) const clientTimeout = 10 * time.Second httpClient := &http.Client{Timeout: clientTimeout} - storage := storage.New(logger, constants.ServersData) - currentServers, err := storage.SyncServers(constants.GetAllServers()) + + storage, err := storage.New(logger, constants.ServersData) if err != nil { - return fmt.Errorf("%w: %s", ErrSyncServers, err) + return fmt.Errorf("%w: %s", ErrNewStorage, err) } + currentServers := storage.GetServers() + updater := updater.New(options, httpClient, currentServers, logger) allServers, err := updater.UpdateServers(ctx) if err != nil { diff --git a/internal/configuration/cyberghost.go b/internal/configuration/cyberghost.go index b66f77bc..15d63d85 100644 --- a/internal/configuration/cyberghost.go +++ b/internal/configuration/cyberghost.go @@ -8,6 +8,7 @@ import ( func (settings *Provider) readCyberghost(r reader) (err error) { settings.Name = constants.Cyberghost + servers := r.servers.GetCyberghost() settings.ServerSelection.TargetIP, err = readTargetIP(r.env) if err != nil { @@ -15,17 +16,18 @@ func (settings *Provider) readCyberghost(r reader) (err error) { } settings.ServerSelection.Groups, err = r.env.CSVInside("CYBERGHOST_GROUP", - constants.CyberghostGroupChoices()) + constants.CyberghostGroupChoices(servers)) if err != nil { return fmt.Errorf("environment variable CYBERGHOST_GROUP: %w", err) } - settings.ServerSelection.Regions, err = r.env.CSVInside("REGION", constants.CyberghostRegionChoices()) + settings.ServerSelection.Regions, err = r.env.CSVInside("REGION", constants.CyberghostRegionChoices(servers)) if err != nil { return fmt.Errorf("environment variable REGION: %w", err) } - settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.CyberghostHostnameChoices()) + settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", + constants.CyberghostHostnameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_HOSTNAME: %w", err) } diff --git a/internal/configuration/fastestvpn.go b/internal/configuration/fastestvpn.go index 7eebdf30..f35657b6 100644 --- a/internal/configuration/fastestvpn.go +++ b/internal/configuration/fastestvpn.go @@ -8,18 +8,20 @@ import ( func (settings *Provider) readFastestvpn(r reader) (err error) { settings.Name = constants.Fastestvpn + servers := r.servers.GetFastestvpn() settings.ServerSelection.TargetIP, err = readTargetIP(r.env) if err != nil { return err } - settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.FastestvpnHostnameChoices()) + settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", + constants.FastestvpnHostnameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_HOSTNAME: %w", err) } - settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.FastestvpnCountriesChoices()) + settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.FastestvpnCountriesChoices(servers)) if err != nil { return fmt.Errorf("environment variable COUNTRY: %w", err) } diff --git a/internal/configuration/health.go b/internal/configuration/health.go index 8ba32d7e..4d0747c3 100644 --- a/internal/configuration/health.go +++ b/internal/configuration/health.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" + "github.com/qdm12/gluetun/internal/models" "github.com/qdm12/golibs/logging" "github.com/qdm12/golibs/params" ) @@ -33,7 +34,7 @@ func (settings *Health) lines() (lines []string) { // Read is to be used for the healthcheck query mode. func (settings *Health) Read(env params.Interface, logger logging.Logger) (err error) { - reader := newReader(env, logger) + reader := newReader(env, models.AllServers{}, logger) // note: no need for servers data return settings.read(reader) } diff --git a/internal/configuration/hidemyass.go b/internal/configuration/hidemyass.go index 9677ff2a..4bae3f15 100644 --- a/internal/configuration/hidemyass.go +++ b/internal/configuration/hidemyass.go @@ -8,28 +8,30 @@ import ( func (settings *Provider) readHideMyAss(r reader) (err error) { settings.Name = constants.HideMyAss + servers := r.servers.GetHideMyAss() settings.ServerSelection.TargetIP, err = readTargetIP(r.env) if err != nil { return err } - settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.HideMyAssCountryChoices()) + settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.HideMyAssCountryChoices(servers)) if err != nil { return fmt.Errorf("environment variable COUNTRY: %w", err) } - settings.ServerSelection.Regions, err = r.env.CSVInside("REGION", constants.HideMyAssCountryChoices()) + settings.ServerSelection.Regions, err = r.env.CSVInside("REGION", constants.HideMyAssCountryChoices(servers)) if err != nil { return fmt.Errorf("environment variable REGION: %w", err) } - settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.HideMyAssCityChoices()) + settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.HideMyAssCityChoices(servers)) if err != nil { return fmt.Errorf("environment variable CITY: %w", err) } - settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.HideMyAssHostnameChoices()) + settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", + constants.HideMyAssHostnameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_HOSTNAME: %w", err) } diff --git a/internal/configuration/ipvanish.go b/internal/configuration/ipvanish.go index 4b9be342..6764ad78 100644 --- a/internal/configuration/ipvanish.go +++ b/internal/configuration/ipvanish.go @@ -8,23 +8,25 @@ import ( func (settings *Provider) readIpvanish(r reader) (err error) { settings.Name = constants.Ipvanish + servers := r.servers.GetIpvanish() settings.ServerSelection.TargetIP, err = readTargetIP(r.env) if err != nil { return err } - settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.IpvanishCountryChoices()) + settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.IpvanishCountryChoices(servers)) if err != nil { return fmt.Errorf("environment variable COUNTRY: %w", err) } - settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.IpvanishCityChoices()) + settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.IpvanishCityChoices(servers)) if err != nil { return fmt.Errorf("environment variable CITY: %w", err) } - settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.IpvanishHostnameChoices()) + settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", + constants.IpvanishHostnameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_HOSTNAME: %w", err) } diff --git a/internal/configuration/ipvanish_test.go b/internal/configuration/ipvanish_test.go index ab51c6fe..6d136f87 100644 --- a/internal/configuration/ipvanish_test.go +++ b/internal/configuration/ipvanish_test.go @@ -7,6 +7,7 @@ import ( "github.com/golang/mock/gomock" "github.com/qdm12/gluetun/internal/constants" + "github.com/qdm12/gluetun/internal/models" "github.com/qdm12/golibs/params/mock_params" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -119,21 +120,28 @@ func Test_Provider_readIpvanish(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) + servers := []models.IpvanishServer{{Hostname: "a"}} + allServers := models.AllServers{ + Ipvanish: models.IpvanishServers{ + Servers: servers, + }, + } + env := mock_params.NewMockInterface(ctrl) if testCase.targetIP.call { env.EXPECT().Get("OPENVPN_TARGET_IP"). Return(testCase.targetIP.value, testCase.targetIP.err) } if testCase.countries.call { - env.EXPECT().CSVInside("COUNTRY", constants.IpvanishCountryChoices()). + env.EXPECT().CSVInside("COUNTRY", constants.IpvanishCountryChoices(servers)). Return(testCase.countries.values, testCase.countries.err) } if testCase.cities.call { - env.EXPECT().CSVInside("CITY", constants.IpvanishCityChoices()). + env.EXPECT().CSVInside("CITY", constants.IpvanishCityChoices(servers)). Return(testCase.cities.values, testCase.cities.err) } if testCase.hostnames.call { - env.EXPECT().CSVInside("SERVER_HOSTNAME", constants.IpvanishHostnameChoices()). + env.EXPECT().CSVInside("SERVER_HOSTNAME", constants.IpvanishHostnameChoices(servers)). Return(testCase.hostnames.values, testCase.hostnames.err) } if testCase.protocol.call { @@ -141,7 +149,10 @@ func Test_Provider_readIpvanish(t *testing.T) { Return(testCase.protocol.value, testCase.protocol.err) } - r := reader{env: env} + r := reader{ + servers: allServers, + env: env, + } var settings Provider err := settings.readIpvanish(r) diff --git a/internal/configuration/ivpn.go b/internal/configuration/ivpn.go index 09bf32e9..25b00c2f 100644 --- a/internal/configuration/ivpn.go +++ b/internal/configuration/ivpn.go @@ -9,28 +9,29 @@ import ( func (settings *Provider) readIvpn(r reader) (err error) { settings.Name = constants.Ivpn + servers := r.servers.GetIvpn() settings.ServerSelection.TargetIP, err = readTargetIP(r.env) if err != nil { return err } - settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.IvpnCountryChoices()) + settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.IvpnCountryChoices(servers)) if err != nil { return fmt.Errorf("environment variable COUNTRY: %w", err) } - settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.IvpnCityChoices()) + settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.IvpnCityChoices(servers)) if err != nil { return fmt.Errorf("environment variable CITY: %w", err) } - settings.ServerSelection.ISPs, err = r.env.CSVInside("ISP", constants.IvpnISPChoices()) + settings.ServerSelection.ISPs, err = r.env.CSVInside("ISP", constants.IvpnISPChoices(servers)) if err != nil { return fmt.Errorf("environment variable ISP: %w", err) } - settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.IvpnHostnameChoices()) + settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.IvpnHostnameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_HOSTNAME: %w", err) } diff --git a/internal/configuration/ivpn_test.go b/internal/configuration/ivpn_test.go index b8c2aa98..31a2df6a 100644 --- a/internal/configuration/ivpn_test.go +++ b/internal/configuration/ivpn_test.go @@ -7,6 +7,7 @@ import ( "github.com/golang/mock/gomock" "github.com/qdm12/gluetun/internal/constants" + "github.com/qdm12/gluetun/internal/models" "github.com/qdm12/golibs/params/mock_params" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -183,24 +184,31 @@ func Test_Provider_readIvpn(t *testing.T) { //nolint:gocognit env := mock_params.NewMockInterface(ctrl) + servers := []models.IvpnServer{{Hostname: "a"}} + allServers := models.AllServers{ + Ivpn: models.IvpnServers{ + Servers: servers, + }, + } + if testCase.targetIP.call { env.EXPECT().Get("OPENVPN_TARGET_IP"). Return(testCase.targetIP.value, testCase.targetIP.err) } if testCase.countries.call { - env.EXPECT().CSVInside("COUNTRY", constants.IvpnCountryChoices()). + env.EXPECT().CSVInside("COUNTRY", constants.IvpnCountryChoices(servers)). Return(testCase.countries.values, testCase.countries.err) } if testCase.cities.call { - env.EXPECT().CSVInside("CITY", constants.IvpnCityChoices()). + env.EXPECT().CSVInside("CITY", constants.IvpnCityChoices(servers)). Return(testCase.cities.values, testCase.cities.err) } if testCase.isps.call { - env.EXPECT().CSVInside("ISP", constants.IvpnISPChoices()). + env.EXPECT().CSVInside("ISP", constants.IvpnISPChoices(servers)). Return(testCase.isps.values, testCase.isps.err) } if testCase.hostnames.call { - env.EXPECT().CSVInside("SERVER_HOSTNAME", constants.IvpnHostnameChoices()). + env.EXPECT().CSVInside("SERVER_HOSTNAME", constants.IvpnHostnameChoices(servers)). Return(testCase.hostnames.values, testCase.hostnames.err) } if testCase.protocol.call { @@ -224,7 +232,10 @@ func Test_Provider_readIvpn(t *testing.T) { //nolint:gocognit Return(testCase.wgPort.portValue, testCase.wgPort.portErr) } - r := reader{env: env} + r := reader{ + servers: allServers, + env: env, + } var settings Provider err := settings.readIvpn(r) diff --git a/internal/configuration/mullvad.go b/internal/configuration/mullvad.go index df057997..db00e509 100644 --- a/internal/configuration/mullvad.go +++ b/internal/configuration/mullvad.go @@ -9,28 +9,29 @@ import ( func (settings *Provider) readMullvad(r reader) (err error) { settings.Name = constants.Mullvad + servers := r.servers.GetMullvad() settings.ServerSelection.TargetIP, err = readTargetIP(r.env) if err != nil { return err } - settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.MullvadCountryChoices()) + settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.MullvadCountryChoices(servers)) if err != nil { return fmt.Errorf("environment variable COUNTRY: %w", err) } - settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.MullvadCityChoices()) + settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.MullvadCityChoices(servers)) if err != nil { return fmt.Errorf("environment variable CITY: %w", err) } - settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.MullvadHostnameChoices()) + settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.MullvadHostnameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_HOSTNAME: %w", err) } - settings.ServerSelection.ISPs, err = r.env.CSVInside("ISP", constants.MullvadISPChoices()) + settings.ServerSelection.ISPs, err = r.env.CSVInside("ISP", constants.MullvadISPChoices(servers)) if err != nil { return fmt.Errorf("environment variable ISP: %w", err) } diff --git a/internal/configuration/nordvpn.go b/internal/configuration/nordvpn.go index 7e112c9c..a72466e2 100644 --- a/internal/configuration/nordvpn.go +++ b/internal/configuration/nordvpn.go @@ -10,23 +10,24 @@ import ( func (settings *Provider) readNordvpn(r reader) (err error) { settings.Name = constants.Nordvpn + servers := r.servers.GetNordvpn() settings.ServerSelection.TargetIP, err = readTargetIP(r.env) if err != nil { return err } - settings.ServerSelection.Regions, err = r.env.CSVInside("REGION", constants.NordvpnRegionChoices()) + settings.ServerSelection.Regions, err = r.env.CSVInside("REGION", constants.NordvpnRegionChoices(servers)) if err != nil { return fmt.Errorf("environment variable REGION: %w", err) } - settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.NordvpnHostnameChoices()) + settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.NordvpnHostnameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_HOSTNAME: %w", err) } - settings.ServerSelection.Names, err = r.env.CSVInside("SERVER_NAME", constants.NordvpnHostnameChoices()) + settings.ServerSelection.Names, err = r.env.CSVInside("SERVER_NAME", constants.NordvpnHostnameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_NAME: %w", err) } diff --git a/internal/configuration/privado.go b/internal/configuration/privado.go index 5979c1b1..52cff26e 100644 --- a/internal/configuration/privado.go +++ b/internal/configuration/privado.go @@ -8,28 +8,29 @@ import ( func (settings *Provider) readPrivado(r reader) (err error) { settings.Name = constants.Privado + servers := r.servers.GetPrivado() settings.ServerSelection.TargetIP, err = readTargetIP(r.env) if err != nil { return err } - settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.PrivadoCountryChoices()) + settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.PrivadoCountryChoices(servers)) if err != nil { return fmt.Errorf("environment variable COUNTRY: %w", err) } - settings.ServerSelection.Regions, err = r.env.CSVInside("REGION", constants.PrivadoRegionChoices()) + settings.ServerSelection.Regions, err = r.env.CSVInside("REGION", constants.PrivadoRegionChoices(servers)) if err != nil { return fmt.Errorf("environment variable REGION: %w", err) } - settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.PrivadoCityChoices()) + settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.PrivadoCityChoices(servers)) if err != nil { return fmt.Errorf("environment variable CITY: %w", err) } - settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.PrivadoHostnameChoices()) + settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.PrivadoHostnameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_HOSTNAME: %w", err) } diff --git a/internal/configuration/privateinternetaccess.go b/internal/configuration/privateinternetaccess.go index 7d58c968..14fa2e89 100644 --- a/internal/configuration/privateinternetaccess.go +++ b/internal/configuration/privateinternetaccess.go @@ -9,23 +9,24 @@ import ( func (settings *Provider) readPrivateInternetAccess(r reader) (err error) { settings.Name = constants.PrivateInternetAccess + servers := r.servers.GetPia() settings.ServerSelection.TargetIP, err = readTargetIP(r.env) if err != nil { return err } - settings.ServerSelection.Regions, err = r.env.CSVInside("REGION", constants.PIAGeoChoices()) + settings.ServerSelection.Regions, err = r.env.CSVInside("REGION", constants.PIAGeoChoices(servers)) if err != nil { return fmt.Errorf("environment variable REGION: %w", err) } - settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.PIAHostnameChoices()) + settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.PIAHostnameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_HOSTNAME: %w", err) } - settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_NAME", constants.PIANameChoices()) + settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_NAME", constants.PIANameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_NAME: %w", err) } diff --git a/internal/configuration/privatevpn.go b/internal/configuration/privatevpn.go index 96b96416..d3818848 100644 --- a/internal/configuration/privatevpn.go +++ b/internal/configuration/privatevpn.go @@ -8,23 +8,25 @@ import ( func (settings *Provider) readPrivatevpn(r reader) (err error) { settings.Name = constants.Privatevpn + servers := r.servers.GetPrivatevpn() settings.ServerSelection.TargetIP, err = readTargetIP(r.env) if err != nil { return err } - settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.PrivatevpnCountryChoices()) + settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.PrivatevpnCountryChoices(servers)) if err != nil { return fmt.Errorf("environment variable COUNTRY: %w", err) } - settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.PrivatevpnCityChoices()) + settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.PrivatevpnCityChoices(servers)) if err != nil { return fmt.Errorf("environment variable CITY: %w", err) } - settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.PrivatevpnHostnameChoices()) + settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", + constants.PrivatevpnHostnameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_HOSTNAME: %w", err) } diff --git a/internal/configuration/protonvpn.go b/internal/configuration/protonvpn.go index 98019b76..0036766b 100644 --- a/internal/configuration/protonvpn.go +++ b/internal/configuration/protonvpn.go @@ -9,33 +9,35 @@ import ( func (settings *Provider) readProtonvpn(r reader) (err error) { settings.Name = constants.Protonvpn + servers := r.servers.GetProtonvpn() settings.ServerSelection.TargetIP, err = readTargetIP(r.env) if err != nil { return err } - settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.ProtonvpnCountryChoices()) + settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.ProtonvpnCountryChoices(servers)) if err != nil { return fmt.Errorf("environment variable COUNTRY: %w", err) } - settings.ServerSelection.Regions, err = r.env.CSVInside("REGION", constants.ProtonvpnRegionChoices()) + settings.ServerSelection.Regions, err = r.env.CSVInside("REGION", constants.ProtonvpnRegionChoices(servers)) if err != nil { return fmt.Errorf("environment variable REGION: %w", err) } - settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.ProtonvpnCityChoices()) + settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.ProtonvpnCityChoices(servers)) if err != nil { return fmt.Errorf("environment variable CITY: %w", err) } - settings.ServerSelection.Names, err = r.env.CSVInside("SERVER_NAME", constants.ProtonvpnNameChoices()) + settings.ServerSelection.Names, err = r.env.CSVInside("SERVER_NAME", constants.ProtonvpnNameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_NAME: %w", err) } - settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.ProtonvpnHostnameChoices()) + settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", + constants.ProtonvpnHostnameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_HOSTNAME: %w", err) } diff --git a/internal/configuration/purevpn.go b/internal/configuration/purevpn.go index c3ff9bb6..34c5e306 100644 --- a/internal/configuration/purevpn.go +++ b/internal/configuration/purevpn.go @@ -8,28 +8,29 @@ import ( func (settings *Provider) readPurevpn(r reader) (err error) { settings.Name = constants.Purevpn + servers := r.servers.GetPurevpn() settings.ServerSelection.TargetIP, err = readTargetIP(r.env) if err != nil { return err } - settings.ServerSelection.Regions, err = r.env.CSVInside("REGION", constants.PurevpnRegionChoices()) + settings.ServerSelection.Regions, err = r.env.CSVInside("REGION", constants.PurevpnRegionChoices(servers)) if err != nil { return fmt.Errorf("environment variable REGION: %w", err) } - settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.PurevpnCountryChoices()) + settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.PurevpnCountryChoices(servers)) if err != nil { return fmt.Errorf("environment variable COUNTRY: %w", err) } - settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.PurevpnCityChoices()) + settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.PurevpnCityChoices(servers)) if err != nil { return fmt.Errorf("environment variable CITY: %w", err) } - settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.PurevpnHostnameChoices()) + settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.PurevpnHostnameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_HOSTNAME: %w", err) } diff --git a/internal/configuration/reader.go b/internal/configuration/reader.go index e9722d29..dec6a503 100644 --- a/internal/configuration/reader.go +++ b/internal/configuration/reader.go @@ -7,22 +7,26 @@ import ( "strconv" "strings" + "github.com/qdm12/gluetun/internal/models" "github.com/qdm12/golibs/logging" "github.com/qdm12/golibs/params" "github.com/qdm12/golibs/verification" ) type reader struct { - env params.Interface - logger logging.Logger - regex verification.Regex + servers models.AllServers + env params.Interface + logger logging.Logger + regex verification.Regex } -func newReader(env params.Interface, logger logging.Logger) reader { +func newReader(env params.Interface, + servers models.AllServers, logger logging.Logger) reader { return reader{ - env: env, - logger: logger, - regex: verification.NewRegex(), + servers: servers, + env: env, + logger: logger, + regex: verification.NewRegex(), } } diff --git a/internal/configuration/settings.go b/internal/configuration/settings.go index 33e9e071..3fa9434f 100644 --- a/internal/configuration/settings.go +++ b/internal/configuration/settings.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" + "github.com/qdm12/gluetun/internal/models" "github.com/qdm12/golibs/logging" "github.com/qdm12/golibs/params" ) @@ -64,8 +65,9 @@ var ( // Read obtains all configuration options for the program and returns an error as soon // as an error is encountered reading them. -func (settings *Settings) Read(env params.Interface, logger logging.Logger) (err error) { - r := newReader(env, logger) +func (settings *Settings) Read(env params.Interface, servers models.AllServers, + logger logging.Logger) (err error) { + r := newReader(env, servers, logger) settings.VersionInformation, err = r.env.OnOff("VERSION_INFORMATION", params.Default("on")) if err != nil { diff --git a/internal/configuration/surfshark.go b/internal/configuration/surfshark.go index d835efc3..d2752e23 100644 --- a/internal/configuration/surfshark.go +++ b/internal/configuration/surfshark.go @@ -10,29 +10,31 @@ import ( func (settings *Provider) readSurfshark(r reader) (err error) { settings.Name = constants.Surfshark + servers := r.servers.GetSurfshark() settings.ServerSelection.TargetIP, err = readTargetIP(r.env) if err != nil { return err } - settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.SurfsharkCountryChoices()) + settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.SurfsharkCountryChoices(servers)) if err != nil { return fmt.Errorf("environment variable COUNTRY: %w", err) } - settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.SurfsharkCityChoices()) + settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.SurfsharkCityChoices(servers)) if err != nil { return fmt.Errorf("environment variable CITY: %w", err) } - settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.SurfsharkHostnameChoices()) + settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", + constants.SurfsharkHostnameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_HOSTNAME: %w", err) } - regionChoices := constants.SurfsharkRegionChoices() - regionChoices = append(regionChoices, constants.SurfsharkRetroLocChoices()...) + regionChoices := constants.SurfsharkRegionChoices(servers) + regionChoices = append(regionChoices, constants.SurfsharkRetroLocChoices(servers)...) regions, err := r.env.CSVInside("REGION", regionChoices) if err != nil { return fmt.Errorf("environment variable REGION: %w", err) diff --git a/internal/configuration/torguard.go b/internal/configuration/torguard.go index 05a9cb1d..8ae96ee2 100644 --- a/internal/configuration/torguard.go +++ b/internal/configuration/torguard.go @@ -8,23 +8,25 @@ import ( func (settings *Provider) readTorguard(r reader) (err error) { settings.Name = constants.Torguard + servers := r.servers.GetTorguard() settings.ServerSelection.TargetIP, err = readTargetIP(r.env) if err != nil { return err } - settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.TorguardCountryChoices()) + settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.TorguardCountryChoices(servers)) if err != nil { return fmt.Errorf("environment variable COUNTRY: %w", err) } - settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.TorguardCityChoices()) + settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.TorguardCityChoices(servers)) if err != nil { return fmt.Errorf("environment variable CITY: %w", err) } - settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.TorguardHostnameChoices()) + settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", + constants.TorguardHostnameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_HOSTNAME: %w", err) } diff --git a/internal/configuration/vpnunlimited.go b/internal/configuration/vpnunlimited.go index 05c65249..e2d8002d 100644 --- a/internal/configuration/vpnunlimited.go +++ b/internal/configuration/vpnunlimited.go @@ -9,23 +9,25 @@ import ( func (settings *Provider) readVPNUnlimited(r reader) (err error) { settings.Name = constants.VPNUnlimited + servers := r.servers.GetVPNUnlimited() settings.ServerSelection.TargetIP, err = readTargetIP(r.env) if err != nil { return err } - settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.VPNUnlimitedCountryChoices()) + settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.VPNUnlimitedCountryChoices(servers)) if err != nil { return fmt.Errorf("environment variable COUNTRY: %w", err) } - settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.VPNUnlimitedCityChoices()) + settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.VPNUnlimitedCityChoices(servers)) if err != nil { return fmt.Errorf("environment variable CITY: %w", err) } - settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.VPNUnlimitedHostnameChoices()) + settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", + constants.VPNUnlimitedHostnameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_HOSTNAME: %w", err) } diff --git a/internal/configuration/vyprvpn.go b/internal/configuration/vyprvpn.go index 4a9cafb2..8d626328 100644 --- a/internal/configuration/vyprvpn.go +++ b/internal/configuration/vyprvpn.go @@ -8,13 +8,14 @@ import ( func (settings *Provider) readVyprvpn(r reader) (err error) { settings.Name = constants.Vyprvpn + servers := r.servers.GetVyprvpn() settings.ServerSelection.TargetIP, err = readTargetIP(r.env) if err != nil { return err } - settings.ServerSelection.Regions, err = r.env.CSVInside("REGION", constants.VyprvpnRegionChoices()) + settings.ServerSelection.Regions, err = r.env.CSVInside("REGION", constants.VyprvpnRegionChoices(servers)) if err != nil { return fmt.Errorf("environment variable REGION: %w", err) } diff --git a/internal/configuration/windscribe.go b/internal/configuration/windscribe.go index a93195a5..e6210e59 100644 --- a/internal/configuration/windscribe.go +++ b/internal/configuration/windscribe.go @@ -9,23 +9,25 @@ import ( func (settings *Provider) readWindscribe(r reader) (err error) { settings.Name = constants.Windscribe + servers := r.servers.GetWindscribe() settings.ServerSelection.TargetIP, err = readTargetIP(r.env) if err != nil { return err } - settings.ServerSelection.Regions, err = r.env.CSVInside("REGION", constants.WindscribeRegionChoices()) + settings.ServerSelection.Regions, err = r.env.CSVInside("REGION", constants.WindscribeRegionChoices(servers)) if err != nil { return fmt.Errorf("environment variable REGION: %w", err) } - settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.WindscribeCityChoices()) + settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.WindscribeCityChoices(servers)) if err != nil { return fmt.Errorf("environment variable CITY: %w", err) } - settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.WindscribeHostnameChoices()) + settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", + constants.WindscribeHostnameChoices(servers)) if err != nil { return fmt.Errorf("environment variable SERVER_HOSTNAME: %w", err) } diff --git a/internal/constants/cyberghost.go b/internal/constants/cyberghost.go index 53e6d1a4..91e09664 100644 --- a/internal/constants/cyberghost.go +++ b/internal/constants/cyberghost.go @@ -11,8 +11,7 @@ const ( CyberghostCertificate = "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" ) -func CyberghostRegionChoices() (choices []string) { - servers := CyberghostServers() +func CyberghostRegionChoices(servers []models.CyberghostServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Region @@ -20,8 +19,7 @@ func CyberghostRegionChoices() (choices []string) { return makeUnique(choices) } -func CyberghostGroupChoices() (choices []string) { - servers := CyberghostServers() +func CyberghostGroupChoices(servers []models.CyberghostServer) (choices []string) { uniqueChoices := map[string]struct{}{} for _, server := range servers { uniqueChoices[server.Group] = struct{}{} @@ -38,19 +36,10 @@ func CyberghostGroupChoices() (choices []string) { return sortable } -func CyberghostHostnameChoices() (choices []string) { - servers := CyberghostServers() +func CyberghostHostnameChoices(servers []models.CyberghostServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Hostname } return makeUnique(choices) } - -// CyberghostServers returns a slice with the server information for each -// of the Cyberghost server. -func CyberghostServers() (servers []models.CyberghostServer) { - servers = make([]models.CyberghostServer, len(allServers.Cyberghost.Servers)) - copy(servers, allServers.Cyberghost.Servers) - return servers -} diff --git a/internal/constants/cyberghost_test.go b/internal/constants/cyberghost_test.go index 3214be6f..cbc8789c 100644 --- a/internal/constants/cyberghost_test.go +++ b/internal/constants/cyberghost_test.go @@ -3,16 +3,29 @@ package constants import ( "testing" + "github.com/golang/mock/gomock" + "github.com/qdm12/gluetun/internal/storage" + "github.com/qdm12/golibs/logging/mock_logging" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func Test_CyberghostGroupChoices(t *testing.T) { t.Parallel() + ctrl := gomock.NewController(t) + + logger := mock_logging.NewMockLogger(ctrl) + logger.EXPECT().Info(gomock.Any()) + + storage, err := storage.New(logger, "") + require.NoError(t, err) + + servers := storage.GetServers() expected := []string{"Premium TCP Asia", "Premium TCP Europe", "Premium TCP USA", "Premium UDP Asia", "Premium UDP Europe", "Premium UDP USA"} - choices := CyberghostGroupChoices() + choices := CyberghostGroupChoices(servers.GetCyberghost()) assert.Equal(t, expected, choices) } diff --git a/internal/constants/fastestvpn.go b/internal/constants/fastestvpn.go index c43e237d..492d3c43 100644 --- a/internal/constants/fastestvpn.go +++ b/internal/constants/fastestvpn.go @@ -10,8 +10,7 @@ const ( FastestvpnOpenvpnStaticKeyV1 = "697fe793b32cb5091d30f2326d5d124a9412e93d0a44ef7361395d76528fcbfc82c3859dccea70a93cfa8fae409709bff75f844cf5ff0c237f426d0c20969233db0e706edb6bdf195ec3dc11b3f76bc807a77e74662d9a800c8cd1144ebb67b7f0d3f1281d1baf522bfe03b7c3f963b1364fc0769400e413b61ca7b43ab19fac9e0f77e41efd4bda7fd77b1de2d7d7855cbbe3e620cecceac72c21a825b243e651f44d90e290e09c3ad650de8fca99c858bc7caad584bc69b11e5c9fd9381c69c505ec487a65912c672d83ed0113b5a74ddfbd3ab33b3683cec593557520a72c4d6cce46111f56f3396cc3ce7183edce553c68ea0796cf6c4375fad00aaa2a42" ) -func FastestvpnCountriesChoices() (choices []string) { - servers := FastestvpnServers() +func FastestvpnCountriesChoices(servers []models.FastestvpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Country @@ -19,18 +18,10 @@ func FastestvpnCountriesChoices() (choices []string) { return choices } -func FastestvpnHostnameChoices() (choices []string) { - servers := FastestvpnServers() +func FastestvpnHostnameChoices(servers []models.FastestvpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Hostname } return choices } - -// FastestvpnServers returns the list of all VPN servers for FastestVPN. -func FastestvpnServers() (servers []models.FastestvpnServer) { - servers = make([]models.FastestvpnServer, len(allServers.Fastestvpn.Servers)) - copy(servers, allServers.Fastestvpn.Servers) - return servers -} diff --git a/internal/constants/hidemyass.go b/internal/constants/hidemyass.go index 82b57c1b..f8aefd76 100644 --- a/internal/constants/hidemyass.go +++ b/internal/constants/hidemyass.go @@ -11,8 +11,7 @@ const ( HideMyAssRSAPrivateKey = "MIIEpAIBAAKCAQEA5XY3ERJYWs/YIeBoybivNlu+M32rJs+CAZsh7BnnetTxytI4ngsMRoqXETuis8udp2hsqEHsglLR9tlk9C8yCuKhxbkpdrXFWdISmUq5sa7/wqg/zJF1AZm5Jy0oHNyTHfG6XW61I/h9IN5dmcR9YLir8DVDBNllbtt0z+DnvOhYJOqC30ENahWkTmNKl1cT7EBrR5slddiBJleAb08z77pwsD310e6jWTBySsBcPy+xu/Jj2QgVil/3mstZZDI+noFzs3SkTFBkha/lNTP7NODBQ6m39iaJxz6ZR1xE3v7XU0H5WnpZIcQ2+kmu5Krk2y1GYMKL+9oaotXFPz9v+QIDAQABAoIBAQCcMcssOMOiFWc3MC3EWo4SP4MKQ9n0Uj5Z34LI151FdJyehlj54+VYQ1Cv71tCbjED2sZUBoP69mtsT/EzcsjqtfiOwgrifrs2+BOm+0HKHKiGlcbP9peiHkT10PxEITWXpYtJvGlbcfOjIxqt6B28cBjCK09ShrVQL9ylAKBearRRUacszppntMNTMtN/uG48ZR9Wm+xAczImdG6CrG5sLI/++JwM5PDChLvn5JgMGyOfQZdjNe1oSOVLmqFeG5uu/FS4oMon9+HtfjHJr4ZgA1yQ2wQh3GvEjlP8zwHxEpRJYbxpj6ZbjHZJ2HLX/Gcd9/cXiN8+fQ2zPIYQyG9dAoGBAPUUmt2nJNvl7gj0GbZZ3XR9o+hvj7bJ74W2NhMrw6kjrrzHTAUQd1sBQS8szAQCLqf2ou1aw9AMMBdsLAHydXxvbH7IBAla7rKr23iethtSfjhTNSgQLJHVZlNHfp3hzNtCQZ7j0qVjrteNotrdVF7kKPHDXAK00ICy6SPNjvrXAoGBAO+vdnO15jLeZbbi3lQNS4r8oCadyqyX7ouKE6MtKNhiPsNPGqHKiGcKs/+QylVgYvSmm7TgpsCAiEYeLSPT+Yq3y7HtwVpULlpfAhEJXmvn/6hGpOizx1WNGWhw7nHPWPDzf+jqCGzHdhK0aEZR3MZZQ+U+uKfGiJ8vrvgB7eGvAoGAWxxp5nU48rcsIw/8bxpBhgkfYk33M5EnBqKSv9XJS5wEXhIJZOiWNrLktNEGl4boKXE7aNoRacreJhcE1UR6AOS7hPZ+6atwiePyF4mJUeb9HZtxa493wk9/Vv6BR9il++1Jz/QKX4oLef8hyBP4Rb60qgxirG7kBLR+j9zfhskCgYEAzA5y5xIeuIIU0H4XUDG9dcebxSSjbwsuYIgeLdb9pjMGQhsvjjyyoh8/nT20tLkJpkXN3FFCRjNnUWLRhWYrVkkh1wqWiYOPrwqh5MU4KN/sDWSPcznTY+drkTpMFoKzsvdrl2zf3VR3FneXKv742bkXj601Ykko+XWMHcLutisCgYBSq8IrsjzfaTQiTGI9a7WWsvzK92bq7Abnfq7swAXWcJd/bnjTQKLrrvt2bmwNvlWKAb3c69BFMn0X4t4PuN0iJQ39D6aQAEaM7HwWAmjf5TbodbmgbGxdsUB4xcCIQQ1mvTkigXWrCg0YAD2GZSoaslXAAVv6nR5qWEIa0Hx9GA==" ) -func HideMyAssCountryChoices() (choices []string) { - servers := HideMyAssServers() +func HideMyAssCountryChoices(servers []models.HideMyAssServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Country @@ -20,8 +19,7 @@ func HideMyAssCountryChoices() (choices []string) { return makeUnique(choices) } -func HideMyAssCityChoices() (choices []string) { - servers := HideMyAssServers() +func HideMyAssCityChoices(servers []models.HideMyAssServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].City @@ -29,18 +27,10 @@ func HideMyAssCityChoices() (choices []string) { return makeUnique(choices) } -func HideMyAssHostnameChoices() (choices []string) { - servers := HideMyAssServers() +func HideMyAssHostnameChoices(servers []models.HideMyAssServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Hostname } return makeUnique(choices) } - -// HideMyAssServers returns a slice of all the server information for HideMyAss. -func HideMyAssServers() (servers []models.HideMyAssServer) { - servers = make([]models.HideMyAssServer, len(allServers.HideMyAss.Servers)) - copy(servers, allServers.HideMyAss.Servers) - return servers -} diff --git a/internal/constants/ipvanish.go b/internal/constants/ipvanish.go index 1b4f3a05..2b86a5cc 100644 --- a/internal/constants/ipvanish.go +++ b/internal/constants/ipvanish.go @@ -9,8 +9,7 @@ const ( IpvanishCA = "MIIErTCCA5WgAwIBAgIJAMYKzSS8uPKDMA0GCSqGSIb3DQEBDQUAMIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCRkwxFDASBgNVBAcTC1dpbnRlciBQYXJrMREwDwYDVQQKEwhJUFZhbmlzaDEVMBMGA1UECxMMSVBWYW5pc2ggVlBOMRQwEgYDVQQDEwtJUFZhbmlzaCBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBpcHZhbmlzaC5jb20wHhcNMTIwMTExMTkzMjIwWhcNMjgxMTAyMTkzMjIwWjCBlTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkZMMRQwEgYDVQQHEwtXaW50ZXIgUGFyazERMA8GA1UEChMISVBWYW5pc2gxFTATBgNVBAsTDElQVmFuaXNoIFZQTjEUMBIGA1UEAxMLSVBWYW5pc2ggQ0ExIzAhBgkqhkiG9w0BCQEWFHN1cHBvcnRAaXB2YW5pc2guY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt9DBWNr/IKOuY3TmDP5x7vYZR0DGxLbXU8TyAzBbjUtFFMbhxlHiXVQrZHmgzih94x7BgXM7tWpmMKYVb+gNaqMdWE680Qm3nOwmhy/dulXDkEHAwD05i/iTx4ZaUdtV2vsKBxRg1vdC4AEiwD7bqV4HOi13xcG971aQ55Mj1KeCdA0aNvpat1LWx2jjWxsfI8s2Lv5Fkoi1HO1+vTnnaEsJZrBgAkLXpItqP29Lik3/OBIvkBIxlKrhiVPixE5qNiD+eSPirsmROvsyIonoJtuY4Dw5K6pcNlKyYiwo1IOFYU3YxffwFJk+bSW4WVBhsdf5dGxq/uOHmuz5gdwxCwIDAQABo4H9MIH6MAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFEv9FCWJHefBcIPX9p8RHCVOGe6uMIHKBgNVHSMEgcIwgb+AFEv9FCWJHefBcIPX9p8RHCVOGe6uoYGbpIGYMIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCRkwxFDASBgNVBAcTC1dpbnRlciBQYXJrMREwDwYDVQQKEwhJUFZhbmlzaDEVMBMGA1UECxMMSVBWYW5pc2ggVlBOMRQwEgYDVQQDEwtJUFZhbmlzaCBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBpcHZhbmlzaC5jb22CCQDGCs0kvLjygzANBgkqhkiG9w0BAQ0FAAOCAQEAI2dkh/43ksV2fdYpVGhYaFZPVqCJoToCez0IvOmLeLGzow+EOSrY508oyjYeNP4VJEjApqo0NrMbKl8g/8bpLBcotOCF1c1HZ+y9v7648uumh01SMjsbBeHOuQcLb+7gX6c0pEmxWv8qj5JiW3/1L1bktnjW5Yp5oFkFSMXjOnIoYKHyKLjN2jtwH6XowUNYpg4qVtKU0CXPdOznWcd9/zSfa393HwJPeeVLbKYaFMC4IEbIUmKYtWyoJ9pJ58smU3pWsHZUg9Zc0LZZNjkNlBdQSLmUHAJ33Bd7pJS0JQeiWviC+4UTmzEWRKa7pDGnYRYNu2cUo0/voStphv8EVA==" ) -func IpvanishCountryChoices() (choices []string) { - servers := IpvanishServers() +func IpvanishCountryChoices(servers []models.IpvanishServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Country @@ -18,8 +17,7 @@ func IpvanishCountryChoices() (choices []string) { return makeUnique(choices) } -func IpvanishCityChoices() (choices []string) { - servers := IpvanishServers() +func IpvanishCityChoices(servers []models.IpvanishServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].City @@ -27,18 +25,10 @@ func IpvanishCityChoices() (choices []string) { return makeUnique(choices) } -func IpvanishHostnameChoices() (choices []string) { - servers := IpvanishServers() +func IpvanishHostnameChoices(servers []models.IpvanishServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Hostname } return makeUnique(choices) } - -// IpvanishServers returns a slice of all the server information for Ipvanish. -func IpvanishServers() (servers []models.IpvanishServer) { - servers = make([]models.IpvanishServer, len(allServers.Ipvanish.Servers)) - copy(servers, allServers.Ipvanish.Servers) - return servers -} diff --git a/internal/constants/ivpn.go b/internal/constants/ivpn.go index 98417dad..7a321993 100644 --- a/internal/constants/ivpn.go +++ b/internal/constants/ivpn.go @@ -10,8 +10,7 @@ const ( IvpnOpenvpnStaticKeyV1 = "ac470c93ff9f5602a8aab37dee84a52814d10f20490ad23c47d5d82120c1bf859e93d0696b455d4a1b8d55d40c2685c41ca1d0aef29a3efd27274c4ef09020a3978fe45784b335da6df2d12db97bbb838416515f2a96f04715fd28949c6fe296a925cfada3f8b8928ed7fc963c1563272f5cf46e5e1d9c845d7703ca881497b7e6564a9d1dea9358adffd435295479f47d5298fabf5359613ff5992cb57ff081a04dfb81a26513a6b44a9b5490ad265f8a02384832a59cc3e075ad545461060b7bcab49bac815163cb80983dd51d5b1fd76170ffd904d8291071e96efc3fb777856c717b148d08a510f5687b8a8285dcffe737b98916dd15ef6235dee4266d3b" ) -func IvpnCountryChoices() (choices []string) { - servers := IvpnServers() +func IvpnCountryChoices(servers []models.IvpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Country @@ -19,8 +18,7 @@ func IvpnCountryChoices() (choices []string) { return makeUnique(choices) } -func IvpnCityChoices() (choices []string) { - servers := IvpnServers() +func IvpnCityChoices(servers []models.IvpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].City @@ -28,8 +26,7 @@ func IvpnCityChoices() (choices []string) { return makeUnique(choices) } -func IvpnISPChoices() (choices []string) { - servers := IvpnServers() +func IvpnISPChoices(servers []models.IvpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].ISP @@ -37,18 +34,10 @@ func IvpnISPChoices() (choices []string) { return makeUnique(choices) } -func IvpnHostnameChoices() (choices []string) { - servers := IvpnServers() +func IvpnHostnameChoices(servers []models.IvpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Hostname } return makeUnique(choices) } - -// IvpnServers returns a slice of all the server information for Ivpn. -func IvpnServers() (servers []models.IvpnServer) { - servers = make([]models.IvpnServer, len(allServers.Ivpn.Servers)) - copy(servers, allServers.Ivpn.Servers) - return servers -} diff --git a/internal/constants/mullvad.go b/internal/constants/mullvad.go index a79c4fca..60240d3d 100644 --- a/internal/constants/mullvad.go +++ b/internal/constants/mullvad.go @@ -9,8 +9,7 @@ const ( MullvadCertificate = "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" ) -func MullvadCountryChoices() (choices []string) { - servers := MullvadServers() +func MullvadCountryChoices(servers []models.MullvadServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Country @@ -18,8 +17,7 @@ func MullvadCountryChoices() (choices []string) { return makeUnique(choices) } -func MullvadCityChoices() (choices []string) { - servers := MullvadServers() +func MullvadCityChoices(servers []models.MullvadServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].City @@ -27,8 +25,7 @@ func MullvadCityChoices() (choices []string) { return makeUnique(choices) } -func MullvadHostnameChoices() (choices []string) { - servers := MullvadServers() +func MullvadHostnameChoices(servers []models.MullvadServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Hostname @@ -36,18 +33,10 @@ func MullvadHostnameChoices() (choices []string) { return makeUnique(choices) } -func MullvadISPChoices() (choices []string) { - servers := MullvadServers() +func MullvadISPChoices(servers []models.MullvadServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].ISP } return makeUnique(choices) } - -// MullvadServers returns a slice of all the server information for Mullvad. -func MullvadServers() (servers []models.MullvadServer) { - servers = make([]models.MullvadServer, len(allServers.Mullvad.Servers)) - copy(servers, allServers.Mullvad.Servers) - return servers -} diff --git a/internal/constants/nordvpn.go b/internal/constants/nordvpn.go index 98c7e7a1..6ebee083 100644 --- a/internal/constants/nordvpn.go +++ b/internal/constants/nordvpn.go @@ -10,8 +10,7 @@ const ( NordvpnOpenvpnStaticKeyV1 = "e685bdaf659a25a200e2b9e39e51ff030fc72cf1ce07232bd8b2be5e6c670143f51e937e670eee09d4f2ea5a6e4e69965db852c275351b86fc4ca892d78ae002d6f70d029bd79c4d1c26cf14e9588033cf639f8a74809f29f72b9d58f9b8f5fefc7938eade40e9fed6cb92184abb2cc10eb1a296df243b251df0643d53724cdb5a92a1d6cb817804c4a9319b57d53be580815bcfcb2df55018cc83fc43bc7ff82d51f9b88364776ee9d12fc85cc7ea5b9741c4f598c485316db066d52db4540e212e1518a9bd4828219e24b20d88f598a196c9de96012090e333519ae18d35099427e7b372d348d352dc4c85e18cd4b93f8a56ddb2e64eb67adfc9b337157ff4" ) -func NordvpnRegionChoices() (choices []string) { - servers := NordvpnServers() +func NordvpnRegionChoices(servers []models.NordvpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Region @@ -19,8 +18,7 @@ func NordvpnRegionChoices() (choices []string) { return makeUnique(choices) } -func NordvpnHostnameChoices() (choices []string) { - servers := NordvpnServers() +func NordvpnHostnameChoices(servers []models.NordvpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Hostname @@ -28,18 +26,10 @@ func NordvpnHostnameChoices() (choices []string) { return makeUnique(choices) } -func NordvpnNameChoices() (choices []string) { - servers := NordvpnServers() +func NordvpnNameChoices(servers []models.NordvpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Name } return makeUnique(choices) } - -// NordvpnServers returns a slice of all the server information for Nordvpn. -func NordvpnServers() (servers []models.NordvpnServer) { - servers = make([]models.NordvpnServer, len(allServers.Nordvpn.Servers)) - copy(servers, allServers.Nordvpn.Servers) - return servers -} diff --git a/internal/constants/pia.go b/internal/constants/pia.go index 4d2ed0f1..365da8c1 100644 --- a/internal/constants/pia.go +++ b/internal/constants/pia.go @@ -15,8 +15,7 @@ const ( PIACertificateStrong = "MIIHqzCCBZOgAwIBAgIJAJ0u+vODZJntMA0GCSqGSIb3DQEBDQUAMIHoMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNVBAoTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UEAxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBCkTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkBFiBzZWN1cmVAcHJpdmF0ZWludGVybmV0YWNjZXNzLmNvbTAeFw0xNDA0MTcxNzQwMzNaFw0zNDA0MTIxNzQwMzNaMIHoMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNVBAoTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UEAxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBCkTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkBFiBzZWN1cmVAcHJpdmF0ZWludGVybmV0YWNjZXNzLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALVkhjumaqBbL8aSgj6xbX1QPTfTd1qHsAZd2B97m8Vw31c/2yQgZNf5qZY0+jOIHULNDe4R9TIvyBEbvnAg/OkPw8n/+ScgYOeH876VUXzjLDBnDb8DLr/+w9oVsuDeFJ9KV2UFM1OYX0SnkHnrYAN2QLF98ESK4NCSU01h5zkcgmQ+qKSfA9Ny0/UpsKPBFqsQ25NvjDWFhCpeqCHKUJ4Be27CDbSl7lAkBuHMPHJs8f8xPgAbHRXZOxVCpayZ2SNDfCwsnGWpWFoMGvdMbygngCn6jA/W1VSFOlRlfLuuGe7QFfDwA0jaLCxuWt/BgZylp7tAzYKR8lnWmtUCPm4+BtjyVDYtDCiGBD9Z4P13RFWvJHw5aapx/5W/CuvVyI7pKwvc2IT+KPxCUhH1XI8ca5RN3C9NoPJJf6qpg4g0rJH3aaWkoMRrYvQ+5PXXYUzjtRHImghRGd/ydERYoAZXuGSbPkm9Y/p2X8unLcW+F0xpJD98+ZI+tzSsI99Zs5wijSUGYr9/j18KHFTMQ8n+1jauc5bCCegN27dPeKXNSZ5riXFL2XX6BkY68y58UaNzmeGMiUL9BOV1iV+PMb7B7PYs7oFLjAhh0EdyvfHkrh/ZV9BEhtFa7yXp8XR0J6vz1YV9R6DYJmLjOEbhU8N0gc3tZm4Qz39lIIG6w3FDAgMBAAGjggFUMIIBUDAdBgNVHQ4EFgQUrsRtyWJftjpdRM0+925Y6Cl08SUwggEfBgNVHSMEggEWMIIBEoAUrsRtyWJftjpdRM0+925Y6Cl08SWhge6kgeswgegxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTETMBEGA1UEBxMKTG9zQW5nZWxlczEgMB4GA1UEChMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBAsTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQDExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UEKRMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxLzAtBgkqhkiG9w0BCQEWIHNlY3VyZUBwcml2YXRlaW50ZXJuZXRhY2Nlc3MuY29tggkAnS7684Nkme0wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQ0FAAOCAgEAJsfhsPk3r8kLXLxY+v+vHzbr4ufNtqnL9/1Uuf8NrsCtpXAoyZ0YqfbkWx3NHTZ7OE9ZRhdMP/RqHQE1p4N4Sa1nZKhTKasV6KhHDqSCt/dvEm89xWm2MVA7nyzQxVlHa9AkcBaemcXEiyT19XdpiXOP4Vhs+J1R5m8zQOxZlV1GtF9vsXmJqWZpOVPmZ8f35BCsYPvv4yMewnrtAC8PFEK/bOPeYcKN50bol22QYaZuLfpkHfNiFTnfMh8sl/ablPyNY7DUNiP5DRcMdIwmfGQxR5WEQoHL3yPJ42LkB5zs6jIm26DGNXfwura/mi105+ENH1CaROtRYwkiHb08U6qLXXJz80mWJkT90nr8Asj35xN2cUppg74nG3YVav/38P48T56hG1NHbYF5uOCske19F6wi9maUoto/3vEr0rnXJUp2KODmKdvBI7co245lHBABWikk8VfejQSlCtDBXn644ZMtAdoxKNfR2WTFVEwJiyd1Fzx0yujuiXDROLhISLQDRjVVAvawrAtLZWYK31bY7KlezPlQnl/D9Asxe85l8jO5+0LdJ6VyOs/Hd4w52alDW/MFySDZSfQHMTIc30hLBJ8OnCEIvluVQQ2UQvoW+no177N9L2Y+M9TcTA62ZyMXShHQGeh20rb4kK8f+iFX8NxtdHVSkxMEFSfDDyQ=" ) -func PIAGeoChoices() (choices []string) { - servers := PIAServers() +func PIAGeoChoices(servers []models.PIAServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Region @@ -24,8 +23,7 @@ func PIAGeoChoices() (choices []string) { return makeUnique(choices) } -func PIAHostnameChoices() (choices []string) { - servers := PIAServers() +func PIAHostnameChoices(servers []models.PIAServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Hostname @@ -33,8 +31,7 @@ func PIAHostnameChoices() (choices []string) { return makeUnique(choices) } -func PIANameChoices() (choices []string) { - servers := PIAServers() +func PIANameChoices(servers []models.PIAServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].ServerName @@ -42,15 +39,8 @@ func PIANameChoices() (choices []string) { return makeUnique(choices) } -// PIAServers returns a slice of all the server information for PIA. -func PIAServers() (servers []models.PIAServer) { - servers = make([]models.PIAServer, len(allServers.Pia.Servers)) - copy(servers, allServers.Pia.Servers) - return servers -} - -func PIAServerWhereName(serverName string) (server models.PIAServer) { - for _, server := range PIAServers() { +func PIAServerWhereName(servers []models.PIAServer, serverName string) (server models.PIAServer) { + for _, server := range servers { if server.ServerName == serverName { return server } diff --git a/internal/constants/privado.go b/internal/constants/privado.go index d84a139d..b64cc2a3 100644 --- a/internal/constants/privado.go +++ b/internal/constants/privado.go @@ -1,16 +1,13 @@ package constants -import ( - "github.com/qdm12/gluetun/internal/models" -) +import "github.com/qdm12/gluetun/internal/models" //nolint:lll const ( PrivadoCertificate = "MIIFKDCCAxCgAwIBAgIJAMtrmqZxIV/OMA0GCSqGSIb3DQEBDQUAMBIxEDAOBgNVBAMMB1ByaXZhZG8wHhcNMjAwMTA4MjEyODQ1WhcNMzUwMTA5MjEyODQ1WjASMRAwDgYDVQQDDAdQcml2YWRvMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxPwOgiwNJzZTnKIXwAB0TSu/Lu2qt2U2I8obtQjwhi/7OrfmbmYykSdro70al2XPhnwAGGdCxW6LDnp0UN/IOhD11mgBPo14f5CLkBQjSJ6VN5miPbvK746LsNZl9H8rQGvDuPo4CG9BfPZMiDRGlsMxij/jztzgT1gmuxQ7WHfFRcNzBas1dHa9hV/d3TU6/t47x4SE/ljdcCtJiu7Zn6ODKQoys3mB7Luz2ngqUJWvkqsg+E4+3eJ0M8Hlbn5TPaRJBID7DAdYo6Vs6xGCYr981ThFcmoIQ10js10yANrrfGAzd03b3TnLAgko0uQMHjliMZL6L8sWOPHxyxJI0us88SFh4UgcFyRHKHPKux7w24SxAlZUYoUcTHp9VjG5XvDKYxzgV2RdM4ulBGbQRQ3y3/CyddsyQYMvA55Ets0LfPaBvDIcct70iXijGsdvlX1du3ArGpG7Vaje/RU4nbbGT6HYRdt5YyZfof288ukMOSj20nVcmS+c/4tqsxSerRb1aq5LOi1IemSkTMeC5gCbexk+L1vl7NT/58sxjGmu5bXwnvev/lIItfi2AlITrfUSEv19iDMKkeshwn/+sFJBMWYyluP+yJ56yR+MWoXvLlSWphLDTqq19yx3BZn0P1tgbXoR0g8PTdJFcz8z3RIb7myVLYulV1oGG/3rka0CAwEAAaOBgDB+MB0GA1UdDgQWBBTFtJkZCVDuDAD6k5bJzefjJdO3DTBCBgNVHSMEOzA5gBTFtJkZCVDuDAD6k5bJzefjJdO3DaEWpBQwEjEQMA4GA1UEAwwHUHJpdmFkb4IJAMtrmqZxIV/OMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBDQUAA4ICAQB7MUSXMeBb9wlSv4sUaT1JHEwE26nlBw+TKmezfuPU5pBlY0LYr6qQZY95DHqsRJ7ByUzGUrGo17dNGXlcuNc6TAaQQEDRPo6y+LVh2TWMk15TUMI+MkqryJtCret7xGvDigKYMJgBy58HN3RAVr1B7cL9youwzLgc2Y/NcFKvnQJKeiIYAJ7g0CcnJiQvgZTS7xdwkEBXfsngmUCIG320DLPEL+Ze0HiUrxwWljMRya6i40AeH3Zu2i532xX1wV5+cjA4RJWIKg6ri/Q54iFGtZrA9/nc6y9uoQHkmz8cGyVUmJxFzMrrIICVqUtVRxLhkTMe4UzwRWTBeGgtW4tS0yq1QonAKfOyjgRw/CeY55D2UGvnAFZdTadtYXS4Alu2P9zdwoEk3fzHiVmDjqfJVr5wz9383aABUFrPI3nz6ed/Z6LZflKh1k+DUDEp8NxU4klUULWsSOKoa5zGX51G8cdHxwQLImXvtGuN5eSR8jCTgxFZhdps/xes4KkyfIz9FMYG748M+uOTgKITf4zdJ9BAyiQaOufVQZ8WjhWzWk9YHec9VqPkzpWNGkVjiRI5ewuXwZzZ164tMv2hikBXSuUCnFz37/ZNwGlDi0oBdDszCk2GxccdFHHaCSmpjU5MrdJ+5IhtTKGeTx+US2hTIVHQFIO99DmacxSYvLNcSQ==" ) -func PrivadoCountryChoices() (choices []string) { - servers := PrivadoServers() +func PrivadoCountryChoices(servers []models.PrivadoServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Country @@ -18,8 +15,7 @@ func PrivadoCountryChoices() (choices []string) { return makeUnique(choices) } -func PrivadoRegionChoices() (choices []string) { - servers := PrivadoServers() +func PrivadoRegionChoices(servers []models.PrivadoServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Region @@ -27,8 +23,7 @@ func PrivadoRegionChoices() (choices []string) { return makeUnique(choices) } -func PrivadoCityChoices() (choices []string) { - servers := PrivadoServers() +func PrivadoCityChoices(servers []models.PrivadoServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].City @@ -36,18 +31,10 @@ func PrivadoCityChoices() (choices []string) { return makeUnique(choices) } -func PrivadoHostnameChoices() (choices []string) { - servers := PrivadoServers() +func PrivadoHostnameChoices(servers []models.PrivadoServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Hostname } return makeUnique(choices) } - -// PrivadoServers returns a slice of all the Privado servers. -func PrivadoServers() (servers []models.PrivadoServer) { - servers = make([]models.PrivadoServer, len(allServers.Privado.Servers)) - copy(servers, allServers.Privado.Servers) - return servers -} diff --git a/internal/constants/privatevpn.go b/internal/constants/privatevpn.go index 86a3971e..51fc3a6a 100644 --- a/internal/constants/privatevpn.go +++ b/internal/constants/privatevpn.go @@ -1,8 +1,6 @@ package constants -import ( - "github.com/qdm12/gluetun/internal/models" -) +import "github.com/qdm12/gluetun/internal/models" //nolint:lll const ( @@ -10,8 +8,7 @@ const ( PrivatevpnOpenvpnStaticKeyV1 = "a49082f082ca89d6a6bb4ecc7c047c6d428a1d3c8254a95206d38a61d7fbe65984214cd7d56eacc5a60803bffd677fa7294d4bfe555036339312de2dfb1335bd9d5fd94b04bba3a15fc5192aeb02fb6d8dd2ca831fad7509be5eefa8d1eaa689dc586c831a23b589c512662652ecf1bb3a4a673816aba434a04f6857b8c2f8bb265bfe48a7b8112539729d2f7d9734a720e1035188118c73fef1824d0237d5579ca382d703b4bb252acaedc753b12199f00154d3769efbcf85ef5ad6ee755cbeaa944cb98e7654286df54c793a8443f5363078e3da548ba0beed079df633283cefb256f6a4bcfc4ab2c4affc24955c1864d5458e84a7c210d0d186269e55dcf6" ) -func PrivatevpnCountryChoices() (choices []string) { - servers := PrivatevpnServers() +func PrivatevpnCountryChoices(servers []models.PrivatevpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Country @@ -19,8 +16,7 @@ func PrivatevpnCountryChoices() (choices []string) { return makeChoicesUnique(choices) } -func PrivatevpnCityChoices() (choices []string) { - servers := PrivatevpnServers() +func PrivatevpnCityChoices(servers []models.PrivatevpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].City @@ -28,17 +24,10 @@ func PrivatevpnCityChoices() (choices []string) { return makeChoicesUnique(choices) } -func PrivatevpnHostnameChoices() (choices []string) { - servers := PrivatevpnServers() +func PrivatevpnHostnameChoices(servers []models.PrivatevpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Hostname } return makeChoicesUnique(choices) } - -func PrivatevpnServers() (servers []models.PrivatevpnServer) { - servers = make([]models.PrivatevpnServer, len(allServers.Privatevpn.Servers)) - copy(servers, allServers.Privatevpn.Servers) - return servers -} diff --git a/internal/constants/protonvpn.go b/internal/constants/protonvpn.go index 9b7405be..d4363375 100644 --- a/internal/constants/protonvpn.go +++ b/internal/constants/protonvpn.go @@ -1,8 +1,6 @@ package constants -import ( - "github.com/qdm12/gluetun/internal/models" -) +import "github.com/qdm12/gluetun/internal/models" //nolint:lll const ( @@ -10,8 +8,7 @@ const ( ProtonvpnOpenvpnStaticKeyV1 = "6acef03f62675b4b1bbd03e53b187727423cea742242106cb2916a8a4c8297563d22c7e5cef430b1103c6f66eb1fc5b375a672f158e2e2e936c3faa48b035a6de17beaac23b5f03b10b868d53d03521d8ba115059da777a60cbfd7b2c9c5747278a15b8f6e68a3ef7fd583ec9f398c8bd4735dab40cbd1e3c62a822e97489186c30a0b48c7c38ea32ceb056d3fa5a710e10ccc7a0ddb363b08c3d2777a3395e10c0b6080f56309192ab5aacd4b45f55da61fc77af39bd81a19218a79762c33862df55785075f37d8c71dc8a42097ee43344739a0dd48d03025b0450cf1fb5e8caeb893d9a96d1f15519bb3c4dcb40ee316672ea16c012664f8a9f11255518deb" ) -func ProtonvpnCountryChoices() (choices []string) { - servers := ProtonvpnServers() +func ProtonvpnCountryChoices(servers []models.ProtonvpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Country @@ -19,8 +16,7 @@ func ProtonvpnCountryChoices() (choices []string) { return makeChoicesUnique(choices) } -func ProtonvpnRegionChoices() (choices []string) { - servers := ProtonvpnServers() +func ProtonvpnRegionChoices(servers []models.ProtonvpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Region @@ -28,8 +24,7 @@ func ProtonvpnRegionChoices() (choices []string) { return makeChoicesUnique(choices) } -func ProtonvpnCityChoices() (choices []string) { - servers := ProtonvpnServers() +func ProtonvpnCityChoices(servers []models.ProtonvpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].City @@ -37,8 +32,7 @@ func ProtonvpnCityChoices() (choices []string) { return makeChoicesUnique(choices) } -func ProtonvpnNameChoices() (choices []string) { - servers := ProtonvpnServers() +func ProtonvpnNameChoices(servers []models.ProtonvpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Name @@ -46,18 +40,10 @@ func ProtonvpnNameChoices() (choices []string) { return makeChoicesUnique(choices) } -func ProtonvpnHostnameChoices() (choices []string) { - servers := ProtonvpnServers() +func ProtonvpnHostnameChoices(servers []models.ProtonvpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Hostname } return makeChoicesUnique(choices) } - -// ProtonvpnServers returns a slice of all the server information for Protonvpn. -func ProtonvpnServers() (servers []models.ProtonvpnServer) { - servers = make([]models.ProtonvpnServer, len(allServers.Protonvpn.Servers)) - copy(servers, allServers.Protonvpn.Servers) - return servers -} diff --git a/internal/constants/purevpn.go b/internal/constants/purevpn.go index 2b101982..ea94445c 100644 --- a/internal/constants/purevpn.go +++ b/internal/constants/purevpn.go @@ -1,8 +1,6 @@ package constants -import ( - "github.com/qdm12/gluetun/internal/models" -) +import "github.com/qdm12/gluetun/internal/models" //nolint:lll const ( @@ -12,8 +10,7 @@ const ( PurevpnOpenvpnStaticKeyV1 = "e30af995f56d07426d9ba1f824730521d4283db4b4d0cdda9c6e8759a3799dcb7939b6a5989160c9660de0f6125cbb1f585b41c074b2fe88ecfcf17eab9a33be1352379cdf74952b588fb161a93e13df9135b2b29038231e02d657a6225705e6868ccb0c384ed11614690a1894bfbeb274cebf1fe9c2329bdd5c8a40fe8820624d2ea7540cd79ab76892db51fc371a3ac5fc9573afecb3fffe3281e61d72e91579d9b03d8cbf7909b3aebf4d90850321ee6b7d0a7846d15c27d8290e031e951e19438a4654663cad975e138f5bc5af89c737ad822f27e19057731f41e1e254cc9c95b7175c622422cde9f1f2cfd3510add94498b4d7133d3729dd214a16b27fb" ) -func PurevpnRegionChoices() (choices []string) { - servers := PurevpnServers() +func PurevpnRegionChoices(servers []models.PurevpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Region @@ -21,8 +18,7 @@ func PurevpnRegionChoices() (choices []string) { return makeUnique(choices) } -func PurevpnCountryChoices() (choices []string) { - servers := PurevpnServers() +func PurevpnCountryChoices(servers []models.PurevpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Country @@ -30,8 +26,7 @@ func PurevpnCountryChoices() (choices []string) { return makeUnique(choices) } -func PurevpnCityChoices() (choices []string) { - servers := PurevpnServers() +func PurevpnCityChoices(servers []models.PurevpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].City @@ -39,18 +34,10 @@ func PurevpnCityChoices() (choices []string) { return makeUnique(choices) } -func PurevpnHostnameChoices() (choices []string) { - servers := PurevpnServers() +func PurevpnHostnameChoices(servers []models.PurevpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Hostname } return makeUnique(choices) } - -// PurevpnServers returns a slice of all the server information for Purevpn. -func PurevpnServers() (servers []models.PurevpnServer) { - servers = make([]models.PurevpnServer, len(allServers.Purevpn.Servers)) - copy(servers, allServers.Purevpn.Servers) - return servers -} diff --git a/internal/constants/servers.go b/internal/constants/servers.go deleted file mode 100644 index 9dc9dac2..00000000 --- a/internal/constants/servers.go +++ /dev/null @@ -1,34 +0,0 @@ -package constants - -import ( - "embed" - "encoding/json" - "sync" - - "github.com/qdm12/gluetun/internal/models" -) - -//go:embed servers.json -var allServersEmbedFS embed.FS //nolint:gochecknoglobals -var allServers models.AllServers //nolint:gochecknoglobals -var parseOnce sync.Once //nolint:gochecknoglobals - -func init() { //nolint:gochecknoinits - // error returned covered by unit test - parseOnce.Do(func() { allServers, _ = parseAllServers() }) -} - -func parseAllServers() (allServers models.AllServers, err error) { - f, err := allServersEmbedFS.Open("servers.json") - if err != nil { - return allServers, err - } - decoder := json.NewDecoder(f) - err = decoder.Decode(&allServers) - return allServers, err -} - -func GetAllServers() models.AllServers { - parseOnce.Do(func() { allServers, _ = parseAllServers() }) // init did not execute, used in tests - return allServers -} diff --git a/internal/constants/surfshark.go b/internal/constants/surfshark.go index 35e011e0..91a51901 100644 --- a/internal/constants/surfshark.go +++ b/internal/constants/surfshark.go @@ -10,8 +10,7 @@ const ( SurfsharkOpenvpnStaticKeyV1 = "b02cb1d7c6fee5d4f89b8de72b51a8d0c7b282631d6fc19be1df6ebae9e2779e6d9f097058a31c97f57f0c35526a44ae09a01d1284b50b954d9246725a1ead1ff224a102ed9ab3da0152a15525643b2eee226c37041dc55539d475183b889a10e18bb94f079a4a49888da566b99783460ece01daaf93548beea6c827d9674897e7279ff1a19cb092659e8c1860fbad0db4ad0ad5732f1af4655dbd66214e552f04ed8fd0104e1d4bf99c249ac229ce169d9ba22068c6c0ab742424760911d4636aafb4b85f0c952a9ce4275bc821391aa65fcd0d2394f006e3fba0fd34c4bc4ab260f4b45dec3285875589c97d3087c9134d3a3aa2f904512e85aa2dc2202498" ) -func SurfsharkRegionChoices() (choices []string) { - servers := SurfsharkServers() +func SurfsharkRegionChoices(servers []models.SurfsharkServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Region @@ -19,8 +18,7 @@ func SurfsharkRegionChoices() (choices []string) { return makeUnique(choices) } -func SurfsharkCountryChoices() (choices []string) { - servers := SurfsharkServers() +func SurfsharkCountryChoices(servers []models.SurfsharkServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Country @@ -28,8 +26,7 @@ func SurfsharkCountryChoices() (choices []string) { return makeUnique(choices) } -func SurfsharkCityChoices() (choices []string) { - servers := SurfsharkServers() +func SurfsharkCityChoices(servers []models.SurfsharkServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].City @@ -38,7 +35,7 @@ func SurfsharkCityChoices() (choices []string) { } // TODO remove in v4. -func SurfsharkRetroLocChoices() (choices []string) { +func SurfsharkRetroLocChoices(servers []models.SurfsharkServer) (choices []string) { locationData := SurfsharkLocationData() choices = make([]string, len(locationData)) for i := range locationData { @@ -222,18 +219,10 @@ func SurfsharkLocationData() (data []models.SurfsharkLocationData) { } } -func SurfsharkHostnameChoices() (choices []string) { - servers := SurfsharkServers() +func SurfsharkHostnameChoices(servers []models.SurfsharkServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Hostname } return makeUnique(choices) } - -// SurfsharkServers returns a slice of all the server information for Surfshark. -func SurfsharkServers() (servers []models.SurfsharkServer) { - servers = make([]models.SurfsharkServer, len(allServers.Surfshark.Servers)) - copy(servers, allServers.Surfshark.Servers) - return servers -} diff --git a/internal/constants/torguard.go b/internal/constants/torguard.go index 992b9dad..9e465894 100644 --- a/internal/constants/torguard.go +++ b/internal/constants/torguard.go @@ -10,8 +10,7 @@ const ( TorguardOpenvpnStaticKeyV1 = "770e8de5fc56e0248cc7b5aab56be80d0e19cbf003c1b3ed68efbaf08613c3a1a019dac6a4b84f13a6198f73229ffc21fa512394e288f82aa2cf0180f01fb3eb1a71e00a077a20f6d7a83633f5b4f47f27e30617eaf8485dd8c722a8606d56b3c183f65da5d3c9001a8cbdb96c793d936251098b24fe52a6dd2472e98cfccbc466e63520d63ade7a0eacc36208c3142a1068236a52142fbb7b3ed83d785e12a28261bccfb3bcb62a8d2f6d18f5df5f3652e59c5627d8d9c8f7877c4d7b08e19a5c363556ba68d392be78b75152dd55ba0f74d45089e84f77f4492d886524ea6c82b9f4dd83d46528d4f5c3b51cfeaf2838d938bd0597c426b0e440434f2c451f" ) -func TorguardCountryChoices() (choices []string) { - servers := TorguardServers() +func TorguardCountryChoices(servers []models.TorguardServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Country @@ -19,8 +18,7 @@ func TorguardCountryChoices() (choices []string) { return makeUnique(choices) } -func TorguardCityChoices() (choices []string) { - servers := TorguardServers() +func TorguardCityChoices(servers []models.TorguardServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].City @@ -28,18 +26,10 @@ func TorguardCityChoices() (choices []string) { return makeUnique(choices) } -func TorguardHostnameChoices() (choices []string) { - servers := TorguardServers() +func TorguardHostnameChoices(servers []models.TorguardServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Hostname } return makeUnique(choices) } - -// TorguardServers returns a slice of all the server information for Torguard. -func TorguardServers() (servers []models.TorguardServer) { - servers = make([]models.TorguardServer, len(allServers.Torguard.Servers)) - copy(servers, allServers.Torguard.Servers) - return servers -} diff --git a/internal/constants/vpnunlimited.go b/internal/constants/vpnunlimited.go index ca19c40c..adddbdcf 100644 --- a/internal/constants/vpnunlimited.go +++ b/internal/constants/vpnunlimited.go @@ -9,8 +9,7 @@ const ( VPNUnlimitedCertificateAuthority = "MIIEjjCCA/egAwIBAgIJAKsVbHBdakXuMA0GCSqGSIb3DQEBBQUAMIHgMQswCQYDVQQGEwJVUzELMAkGA1UECBMCTlkxETAPBgNVBAcTCE5ldyBZb3JrMR8wHQYDVQQKExZTaW1wbGV4IFNvbHV0aW9ucyBJbmMuMRYwFAYDVQQLEw1WcG4gVW5saW1pdGVkMSMwIQYDVQQDExpzZXJ2ZXIudnBudW5saW1pdGVkYXBwLmNvbTEjMCEGA1UEKRMac2VydmVyLnZwbnVubGltaXRlZGFwcC5jb20xLjAsBgkqhkiG9w0BCQEWH3N1cHBvcnRAc2ltcGxleHNvbHV0aW9uc2luYy5jb20wHhcNMTMxMjE2MTM1OTQ0WhcNMjMxMjE0MTM1OTQ0WjCB4DELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk5ZMREwDwYDVQQHEwhOZXcgWW9yazEfMB0GA1UEChMWU2ltcGxleCBTb2x1dGlvbnMgSW5jLjEWMBQGA1UECxMNVnBuIFVubGltaXRlZDEjMCEGA1UEAxMac2VydmVyLnZwbnVubGltaXRlZGFwcC5jb20xIzAhBgNVBCkTGnNlcnZlci52cG51bmxpbWl0ZWRhcHAuY29tMS4wLAYJKoZIhvcNAQkBFh9zdXBwb3J0QHNpbXBsZXhzb2x1dGlvbnNpbmMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDADUzS8QWGvdhLFKsEzAiq5+b0ukKjBza0k6/dmCeYTvCVqGKg/h1IAtQdVVLAkmEp0zvGH7PuOhXm7zZrCouBr/RiG4tEcoRHwc6AJmowkYERlY7+xGx3OuNrD00QceNTsan0bn78jwt0zhFNmHdoTtFjgK3oqmQYSAtbEVWYgwIDAQABo4IBTDCCAUgwHQYDVR0OBBYEFKClmYP+tMNgWagUJCCHjtaui2k+MIIBFwYDVR0jBIIBDjCCAQqAFKClmYP+tMNgWagUJCCHjtaui2k+oYHmpIHjMIHgMQswCQYDVQQGEwJVUzELMAkGA1UECBMCTlkxETAPBgNVBAcTCE5ldyBZb3JrMR8wHQYDVQQKExZTaW1wbGV4IFNvbHV0aW9ucyBJbmMuMRYwFAYDVQQLEw1WcG4gVW5saW1pdGVkMSMwIQYDVQQDExpzZXJ2ZXIudnBudW5saW1pdGVkYXBwLmNvbTEjMCEGA1UEKRMac2VydmVyLnZwbnVubGltaXRlZGFwcC5jb20xLjAsBgkqhkiG9w0BCQEWH3N1cHBvcnRAc2ltcGxleHNvbHV0aW9uc2luYy5jb22CCQCrFWxwXWpF7jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBALkWhfw7SSV7it+ZYZmT+cQbExjlYgQ40zae2J2CqIYACRcfsDHvh7Q+fiwSocevv2NE0dWi6WB2H6SiudYjvDvubAX/QbzfBxtbxCCoAIlfPCm8xOnWFN7TUJAzWwHJkKgEnu29GZHu2x8J+7VeDbKH5RTMHHe8FkSxh6Zz/BMN" ) -func VPNUnlimitedCountryChoices() (choices []string) { - servers := VPNUnlimitedServers() +func VPNUnlimitedCountryChoices(servers []models.VPNUnlimitedServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Country @@ -18,8 +17,7 @@ func VPNUnlimitedCountryChoices() (choices []string) { return makeUnique(choices) } -func VPNUnlimitedCityChoices() (choices []string) { - servers := VPNUnlimitedServers() +func VPNUnlimitedCityChoices(servers []models.VPNUnlimitedServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].City @@ -27,18 +25,10 @@ func VPNUnlimitedCityChoices() (choices []string) { return makeUnique(choices) } -func VPNUnlimitedHostnameChoices() (choices []string) { - servers := VPNUnlimitedServers() +func VPNUnlimitedHostnameChoices(servers []models.VPNUnlimitedServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Hostname } return makeUnique(choices) } - -// VPNUnlimitedServers returns a slice of all the server information for VPNUnlimited. -func VPNUnlimitedServers() (servers []models.VPNUnlimitedServer) { - servers = make([]models.VPNUnlimitedServer, len(allServers.VPNUnlimited.Servers)) - copy(servers, allServers.VPNUnlimited.Servers) - return servers -} diff --git a/internal/constants/vyprvpn.go b/internal/constants/vyprvpn.go index 81c116f2..2f9f4ef9 100644 --- a/internal/constants/vyprvpn.go +++ b/internal/constants/vyprvpn.go @@ -9,18 +9,10 @@ const ( VyprvpnCertificate = "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" ) -func VyprvpnRegionChoices() (choices []string) { - servers := VyprvpnServers() +func VyprvpnRegionChoices(servers []models.VyprvpnServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Region } return makeUnique(choices) } - -// VyprvpnServers returns a slice of all the VyprVPN servers. -func VyprvpnServers() (servers []models.VyprvpnServer) { - servers = make([]models.VyprvpnServer, len(allServers.Vyprvpn.Servers)) - copy(servers, allServers.Vyprvpn.Servers) - return servers -} diff --git a/internal/constants/windscribe.go b/internal/constants/windscribe.go index 1fd88c5b..c41a62d0 100644 --- a/internal/constants/windscribe.go +++ b/internal/constants/windscribe.go @@ -1,8 +1,6 @@ package constants -import ( - "github.com/qdm12/gluetun/internal/models" -) +import "github.com/qdm12/gluetun/internal/models" //nolint:lll const ( @@ -10,8 +8,7 @@ const ( WindscribeOpenvpnStaticKeyV1 = "5801926a57ac2ce27e3dfd1dd6ef82042d82bd4f3f0021296f57734f6f1ea714a6623845541c4b0c3dea0a050fe6746cb66dfab14cda27e5ae09d7c155aa554f399fa4a863f0e8c1af787e5c602a801d3a2ec41e395a978d56729457fe6102d7d9e9119aa83643210b33c678f9d4109e3154ac9c759e490cb309b319cf708cae83ddadc3060a7a26564d1a24411cd552fe6620ea16b755697a4fc5e6e9d0cfc0c5c4a1874685429046a424c026db672e4c2c492898052ba59128d46200b40f880027a8b6610a4d559bdc9346d33a0a6b08e75c7fd43192b162bfd0aef0c716b31584827693f676f9a5047123466f0654eade34972586b31c6ce7e395f4b478cb" ) -func WindscribeRegionChoices() (choices []string) { - servers := WindscribeServers() +func WindscribeRegionChoices(servers []models.WindscribeServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Region @@ -19,8 +16,7 @@ func WindscribeRegionChoices() (choices []string) { return makeUnique(choices) } -func WindscribeCityChoices() (choices []string) { - servers := WindscribeServers() +func WindscribeCityChoices(servers []models.WindscribeServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].City @@ -28,18 +24,10 @@ func WindscribeCityChoices() (choices []string) { return makeUnique(choices) } -func WindscribeHostnameChoices() (choices []string) { - servers := WindscribeServers() +func WindscribeHostnameChoices(servers []models.WindscribeServer) (choices []string) { choices = make([]string, len(servers)) for i := range servers { choices[i] = servers[i].Hostname } return makeUnique(choices) } - -// WindscribeServers returns a slice of all the Windscribe servers. -func WindscribeServers() (servers []models.WindscribeServer) { - servers = make([]models.WindscribeServer, len(allServers.Windscribe.Servers)) - copy(servers, allServers.Windscribe.Servers) - return servers -} diff --git a/internal/models/getservers.go b/internal/models/getservers.go new file mode 100644 index 00000000..0caf3a68 --- /dev/null +++ b/internal/models/getservers.go @@ -0,0 +1,252 @@ +package models + +import ( + "net" +) + +func (a AllServers) GetCopy() (servers AllServers) { + servers = a // copy versions and timestamps + servers.Cyberghost.Servers = a.GetCyberghost() + servers.Fastestvpn.Servers = a.GetFastestvpn() + servers.HideMyAss.Servers = a.GetHideMyAss() + servers.Ipvanish.Servers = a.GetIpvanish() + servers.Ivpn.Servers = a.GetIvpn() + servers.Mullvad.Servers = a.GetMullvad() + servers.Nordvpn.Servers = a.GetNordvpn() + servers.Privado.Servers = a.GetPrivado() + servers.Pia.Servers = a.GetPia() + servers.Privatevpn.Servers = a.GetPrivatevpn() + servers.Protonvpn.Servers = a.GetProtonvpn() + servers.Purevpn.Servers = a.GetPurevpn() + servers.Surfshark.Servers = a.GetSurfshark() + servers.Torguard.Servers = a.GetTorguard() + servers.VPNUnlimited.Servers = a.GetVPNUnlimited() + servers.Vyprvpn.Servers = a.GetVyprvpn() + servers.Windscribe.Servers = a.GetWindscribe() + return servers +} + +func (a *AllServers) GetCyberghost() (servers []CyberghostServer) { + if a.Cyberghost.Servers == nil { + return nil + } + servers = make([]CyberghostServer, len(a.Cyberghost.Servers)) + for i, serverToCopy := range a.Cyberghost.Servers { + servers[i] = serverToCopy + servers[i].IPs = copyIPs(serverToCopy.IPs) + } + return servers +} + +func (a *AllServers) GetFastestvpn() (servers []FastestvpnServer) { + if a.Fastestvpn.Servers == nil { + return nil + } + servers = make([]FastestvpnServer, len(a.Fastestvpn.Servers)) + for i, serverToCopy := range a.Fastestvpn.Servers { + servers[i] = serverToCopy + servers[i].IPs = copyIPs(serverToCopy.IPs) + } + return servers +} + +func (a *AllServers) GetHideMyAss() (servers []HideMyAssServer) { + if a.HideMyAss.Servers == nil { + return nil + } + servers = make([]HideMyAssServer, len(a.HideMyAss.Servers)) + for i, serverToCopy := range a.HideMyAss.Servers { + servers[i] = serverToCopy + servers[i].IPs = copyIPs(serverToCopy.IPs) + } + return servers +} + +func (a *AllServers) GetIpvanish() (servers []IpvanishServer) { + if a.Ipvanish.Servers == nil { + return nil + } + servers = make([]IpvanishServer, len(a.Ipvanish.Servers)) + for i, serverToCopy := range a.Ipvanish.Servers { + servers[i] = serverToCopy + servers[i].IPs = copyIPs(serverToCopy.IPs) + } + return servers +} + +func (a *AllServers) GetIvpn() (servers []IvpnServer) { + if a.Ivpn.Servers == nil { + return nil + } + servers = make([]IvpnServer, len(a.Ivpn.Servers)) + for i, serverToCopy := range a.Ivpn.Servers { + servers[i] = serverToCopy + servers[i].IPs = copyIPs(serverToCopy.IPs) + } + return servers +} + +func (a *AllServers) GetMullvad() (servers []MullvadServer) { + if a.Mullvad.Servers == nil { + return nil + } + servers = make([]MullvadServer, len(a.Mullvad.Servers)) + for i, serverToCopy := range a.Mullvad.Servers { + servers[i] = serverToCopy + servers[i].IPs = copyIPs(serverToCopy.IPs) + servers[i].IPsV6 = copyIPs(serverToCopy.IPsV6) + } + return servers +} + +func (a *AllServers) GetNordvpn() (servers []NordvpnServer) { + if a.Nordvpn.Servers == nil { + return nil + } + servers = make([]NordvpnServer, len(a.Nordvpn.Servers)) + for i, serverToCopy := range a.Nordvpn.Servers { + servers[i] = serverToCopy + servers[i].IP = copyIP(serverToCopy.IP) + } + return servers +} + +func (a *AllServers) GetPia() (servers []PIAServer) { + if a.Pia.Servers == nil { + return nil + } + servers = make([]PIAServer, len(a.Pia.Servers)) + for i, serverToCopy := range a.Pia.Servers { + servers[i] = serverToCopy + servers[i].IPs = copyIPs(serverToCopy.IPs) + } + return servers +} + +func (a *AllServers) GetPrivado() (servers []PrivadoServer) { + if a.Privado.Servers == nil { + return nil + } + servers = make([]PrivadoServer, len(a.Privado.Servers)) + for i, serverToCopy := range a.Privado.Servers { + servers[i] = serverToCopy + servers[i].IP = copyIP(serverToCopy.IP) + } + return servers +} + +func (a *AllServers) GetPrivatevpn() (servers []PrivatevpnServer) { + if a.Privatevpn.Servers == nil { + return nil + } + servers = make([]PrivatevpnServer, len(a.Privatevpn.Servers)) + for i, serverToCopy := range a.Privatevpn.Servers { + servers[i] = serverToCopy + servers[i].IPs = copyIPs(serverToCopy.IPs) + } + return servers +} + +func (a *AllServers) GetProtonvpn() (servers []ProtonvpnServer) { + if a.Protonvpn.Servers == nil { + return nil + } + servers = make([]ProtonvpnServer, len(a.Protonvpn.Servers)) + for i, serverToCopy := range a.Protonvpn.Servers { + servers[i] = serverToCopy + servers[i].EntryIP = copyIP(serverToCopy.EntryIP) + servers[i].ExitIP = copyIP(serverToCopy.ExitIP) + } + return servers +} + +func (a *AllServers) GetPurevpn() (servers []PurevpnServer) { + if a.Purevpn.Servers == nil { + return nil + } + servers = make([]PurevpnServer, len(a.Purevpn.Servers)) + for i, serverToCopy := range a.Purevpn.Servers { + servers[i] = serverToCopy + servers[i].IPs = copyIPs(serverToCopy.IPs) + } + return servers +} + +func (a *AllServers) GetSurfshark() (servers []SurfsharkServer) { + if a.Surfshark.Servers == nil { + return nil + } + servers = make([]SurfsharkServer, len(a.Surfshark.Servers)) + for i, serverToCopy := range a.Surfshark.Servers { + servers[i] = serverToCopy + servers[i].IPs = copyIPs(serverToCopy.IPs) + } + return servers +} + +func (a *AllServers) GetTorguard() (servers []TorguardServer) { + if a.Torguard.Servers == nil { + return nil + } + servers = make([]TorguardServer, len(a.Torguard.Servers)) + for i, serverToCopy := range a.Torguard.Servers { + servers[i] = serverToCopy + servers[i].IPs = copyIPs(serverToCopy.IPs) + } + return servers +} + +func (a *AllServers) GetVPNUnlimited() (servers []VPNUnlimitedServer) { + if a.VPNUnlimited.Servers == nil { + return nil + } + servers = make([]VPNUnlimitedServer, len(a.VPNUnlimited.Servers)) + for i, serverToCopy := range a.VPNUnlimited.Servers { + servers[i] = serverToCopy + servers[i].IPs = copyIPs(serverToCopy.IPs) + } + return servers +} + +func (a *AllServers) GetVyprvpn() (servers []VyprvpnServer) { + if a.Vyprvpn.Servers == nil { + return nil + } + servers = make([]VyprvpnServer, len(a.Vyprvpn.Servers)) + for i, serverToCopy := range a.Vyprvpn.Servers { + servers[i] = serverToCopy + servers[i].IPs = copyIPs(serverToCopy.IPs) + } + return servers +} + +func (a *AllServers) GetWindscribe() (servers []WindscribeServer) { + if a.Windscribe.Servers == nil { + return nil + } + servers = make([]WindscribeServer, len(a.Windscribe.Servers)) + for i, serverToCopy := range a.Windscribe.Servers { + servers[i] = serverToCopy + servers[i].IPs = copyIPs(serverToCopy.IPs) + } + return servers +} + +func copyIPs(toCopy []net.IP) (copied []net.IP) { + if toCopy == nil { + return nil + } + + copied = make([]net.IP, len(toCopy)) + for i := range toCopy { + copied[i] = copyIP(toCopy[i]) + } + + return copied +} + +func copyIP(toCopy net.IP) (copied net.IP) { + copied = make(net.IP, len(toCopy)) + copy(copied, toCopy) + return copied +} diff --git a/internal/models/getservers_test.go b/internal/models/getservers_test.go new file mode 100644 index 00000000..cabdef5f --- /dev/null +++ b/internal/models/getservers_test.go @@ -0,0 +1,181 @@ +package models + +import ( + "net" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func Test_AllServers_GetCopy(t *testing.T) { + allServers := AllServers{ + Cyberghost: CyberghostServers{ + Version: 2, + Servers: []CyberghostServer{{ + IPs: []net.IP{{1, 2, 3, 4}}, + }}, + }, + Fastestvpn: FastestvpnServers{ + Servers: []FastestvpnServer{{ + IPs: []net.IP{{1, 2, 3, 4}}, + }}, + }, + HideMyAss: HideMyAssServers{ + Servers: []HideMyAssServer{{ + IPs: []net.IP{{1, 2, 3, 4}}, + }}, + }, + Ipvanish: IpvanishServers{ + Servers: []IpvanishServer{{ + IPs: []net.IP{{1, 2, 3, 4}}, + }}, + }, + Ivpn: IvpnServers{ + Servers: []IvpnServer{{ + IPs: []net.IP{{1, 2, 3, 4}}, + }}, + }, + Mullvad: MullvadServers{ + Servers: []MullvadServer{{ + IPs: []net.IP{{1, 2, 3, 4}}, + }}, + }, + Nordvpn: NordvpnServers{ + Servers: []NordvpnServer{{ + IP: net.IP{1, 2, 3, 4}, + }}, + }, + Privado: PrivadoServers{ + Servers: []PrivadoServer{{ + IP: net.IP{1, 2, 3, 4}, + }}, + }, + Pia: PiaServers{ + Servers: []PIAServer{{ + IPs: []net.IP{{1, 2, 3, 4}}, + }}, + }, + Privatevpn: PrivatevpnServers{ + Servers: []PrivatevpnServer{{ + IPs: []net.IP{{1, 2, 3, 4}}, + }}, + }, + Protonvpn: ProtonvpnServers{ + Servers: []ProtonvpnServer{{ + EntryIP: net.IP{1, 2, 3, 4}, + ExitIP: net.IP{1, 2, 3, 4}, + }}, + }, + Purevpn: PurevpnServers{ + Version: 1, + Servers: []PurevpnServer{{ + IPs: []net.IP{{1, 2, 3, 4}}, + }}, + }, + Surfshark: SurfsharkServers{ + Servers: []SurfsharkServer{{ + IPs: []net.IP{{1, 2, 3, 4}}, + }}, + }, + Torguard: TorguardServers{ + Servers: []TorguardServer{{ + IPs: []net.IP{{1, 2, 3, 4}}, + }}, + }, + VPNUnlimited: VPNUnlimitedServers{ + Servers: []VPNUnlimitedServer{{ + IPs: []net.IP{{1, 2, 3, 4}}, + }}, + }, + Vyprvpn: VyprvpnServers{ + Servers: []VyprvpnServer{{ + IPs: []net.IP{{1, 2, 3, 4}}, + }}, + }, + Windscribe: WindscribeServers{ + Servers: []WindscribeServer{{ + IPs: []net.IP{{1, 2, 3, 4}}, + }}, + }, + } + + servers := allServers.GetCopy() + + assert.Equal(t, allServers, servers) +} + +func Test_AllServers_GetVyprvpn(t *testing.T) { + allServers := AllServers{ + Vyprvpn: VyprvpnServers{ + Servers: []VyprvpnServer{ + {Hostname: "a", IPs: []net.IP{{1, 1, 1, 1}}}, + {Hostname: "b", IPs: []net.IP{{2, 2, 2, 2}}}, + }, + }, + } + + servers := allServers.GetVyprvpn() + + expectedServers := []VyprvpnServer{ + {Hostname: "a", IPs: []net.IP{{1, 1, 1, 1}}}, + {Hostname: "b", IPs: []net.IP{{2, 2, 2, 2}}}, + } + assert.Equal(t, expectedServers, servers) + + allServers.Vyprvpn.Servers[0].IPs[0][0] = 9 + assert.NotEqual(t, 9, servers[0].IPs[0][0]) + + allServers.Vyprvpn.Servers[0].IPs[0][0] = 1 + servers[0].IPs[0][0] = 9 + assert.NotEqual(t, 9, allServers.Vyprvpn.Servers[0].IPs[0][0]) +} + +func Test_copyIPs(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + toCopy []net.IP + copied []net.IP + }{ + "nil": {}, + "empty": { + toCopy: []net.IP{}, + copied: []net.IP{}, + }, + "single IP": { + toCopy: []net.IP{{1, 1, 1, 1}}, + copied: []net.IP{{1, 1, 1, 1}}, + }, + "two IPs": { + toCopy: []net.IP{{1, 1, 1, 1}, {2, 2, 2, 2}}, + copied: []net.IP{{1, 1, 1, 1}, {2, 2, 2, 2}}, + }, + } + + for name, testCase := range testCases { + testCase := testCase + t.Run(name, func(t *testing.T) { + t.Parallel() + + // Reserver leading 9 for copy modifications below + for _, ipToCopy := range testCase.toCopy { + require.NotEqual(t, 9, ipToCopy[0]) + } + + copied := copyIPs(testCase.toCopy) + + assert.Equal(t, testCase.copied, copied) + + if len(copied) > 0 { + original := testCase.toCopy[0][0] + testCase.toCopy[0][0] = 9 + assert.NotEqual(t, 9, copied[0][0]) + testCase.toCopy[0][0] = original + + copied[0][0] = 9 + assert.NotEqual(t, 9, testCase.toCopy[0][0]) + } + }) + } +} diff --git a/internal/provider/cyberghost/filter.go b/internal/provider/cyberghost/filter.go index b1ed9348..4b3a3cfb 100644 --- a/internal/provider/cyberghost/filter.go +++ b/internal/provider/cyberghost/filter.go @@ -17,9 +17,9 @@ func (c *Cyberghost) filterServers(selection configuration.ServerSelection) ( servers []models.CyberghostServer, err error) { if len(selection.Groups) == 0 { if selection.OpenVPN.TCP { - selection.Groups = tcpGroupChoices() + selection.Groups = tcpGroupChoices(c.servers) } else { - selection.Groups = udpGroupChoices() + selection.Groups = udpGroupChoices(c.servers) } } @@ -50,18 +50,18 @@ func (c *Cyberghost) filterServers(selection configuration.ServerSelection) ( return servers, nil } -func tcpGroupChoices() (choices []string) { +func tcpGroupChoices(servers []models.CyberghostServer) (choices []string) { const tcp = true - return groupsForTCP(tcp) + return groupsForTCP(servers, tcp) } -func udpGroupChoices() (choices []string) { +func udpGroupChoices(servers []models.CyberghostServer) (choices []string) { const tcp = false - return groupsForTCP(tcp) + return groupsForTCP(servers, tcp) } -func groupsForTCP(tcp bool) (choices []string) { - allGroups := constants.CyberghostGroupChoices() +func groupsForTCP(servers []models.CyberghostServer, tcp bool) (choices []string) { + allGroups := constants.CyberghostGroupChoices(servers) choices = make([]string, 0, len(allGroups)) for _, group := range allGroups { switch { diff --git a/internal/provider/cyberghost/filter_test.go b/internal/provider/cyberghost/filter_test.go index 1ae94292..1d238738 100644 --- a/internal/provider/cyberghost/filter_test.go +++ b/internal/provider/cyberghost/filter_test.go @@ -21,7 +21,7 @@ func Test_Cyberghost_filterServers(t *testing.T) { }{ "no server": { selection: configuration.ServerSelection{VPN: constants.OpenVPN}, - err: errors.New("no server found: for VPN openvpn; protocol udp; groups Premium UDP Asia, Premium UDP Europe, Premium UDP USA"), //nolint:lll + err: errors.New("no server found: for VPN openvpn; protocol udp"), }, "servers without filter defaults to UDP": { servers: []models.CyberghostServer{ @@ -146,10 +146,18 @@ func Test_Cyberghost_filterServers(t *testing.T) { func Test_tcpGroupChoices(t *testing.T) { t.Parallel() + servers := []models.CyberghostServer{ + {Group: "Premium TCP Asia"}, + {Group: "Premium TCP Europe"}, + {Group: "Premium TCP USA"}, + {Group: "Premium UDP Asia"}, + {Group: "Premium UDP Europe"}, + {Group: "Premium UDP USA"}, + } expected := []string{ "Premium TCP Asia", "Premium TCP Europe", "Premium TCP USA", } - choices := tcpGroupChoices() + choices := tcpGroupChoices(servers) assert.Equal(t, expected, choices) } @@ -157,10 +165,18 @@ func Test_tcpGroupChoices(t *testing.T) { func Test_udpGroupChoices(t *testing.T) { t.Parallel() + servers := []models.CyberghostServer{ + {Group: "Premium TCP Asia"}, + {Group: "Premium TCP Europe"}, + {Group: "Premium TCP USA"}, + {Group: "Premium UDP Asia"}, + {Group: "Premium UDP Europe"}, + {Group: "Premium UDP USA"}, + } expected := []string{ "Premium UDP Asia", "Premium UDP Europe", "Premium UDP USA", } - choices := udpGroupChoices() + choices := udpGroupChoices(servers) assert.Equal(t, expected, choices) } diff --git a/internal/provider/privateinternetaccess/portforward.go b/internal/provider/privateinternetaccess/portforward.go index 91b43f39..ddcf86a3 100644 --- a/internal/provider/privateinternetaccess/portforward.go +++ b/internal/provider/privateinternetaccess/portforward.go @@ -33,7 +33,7 @@ var ( func (p *PIA) PortForward(ctx context.Context, client *http.Client, logger logging.Logger, gateway net.IP, serverName string) ( port uint16, err error) { - server := constants.PIAServerWhereName(serverName) + server := constants.PIAServerWhereName(p.servers, serverName) if !server.PortForward { logger.Error("The server " + serverName + " (region " + server.Region + ") does not support port forwarding") diff --git a/internal/storage/flush.go b/internal/storage/flush.go index 4846905f..9ea29f7c 100644 --- a/internal/storage/flush.go +++ b/internal/storage/flush.go @@ -1,7 +1,38 @@ package storage -import "github.com/qdm12/gluetun/internal/models" +import ( + "encoding/json" + "os" + "path/filepath" -func (s *storage) FlushToFile(allServers models.AllServers) error { + "github.com/qdm12/gluetun/internal/models" +) + +var _ Flusher = (*Storage)(nil) + +type Flusher interface { + FlushToFile(allServers models.AllServers) error +} + +func (s *Storage) FlushToFile(allServers models.AllServers) error { return flushToFile(s.filepath, allServers) } + +func flushToFile(path string, servers models.AllServers) error { + dirPath := filepath.Dir(path) + if err := os.MkdirAll(dirPath, 0644); err != nil { + return err + } + + file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) + if err != nil { + return err + } + encoder := json.NewEncoder(file) + encoder.SetIndent("", " ") + if err := encoder.Encode(servers); err != nil { + _ = file.Close() + return err + } + return file.Close() +} diff --git a/internal/storage/hardcoded.go b/internal/storage/hardcoded.go new file mode 100644 index 00000000..845b1c52 --- /dev/null +++ b/internal/storage/hardcoded.go @@ -0,0 +1,21 @@ +package storage + +import ( + "embed" + "encoding/json" + + "github.com/qdm12/gluetun/internal/models" +) + +//go:embed servers.json +var allServersEmbedFS embed.FS //nolint:gochecknoglobals + +func parseHardcodedServers() (allServers models.AllServers, err error) { + f, err := allServersEmbedFS.Open("servers.json") + if err != nil { + return allServers, err + } + decoder := json.NewDecoder(f) + err = decoder.Decode(&allServers) + return allServers, err +} diff --git a/internal/constants/servers_test.go b/internal/storage/hardcoded_test.go similarity index 94% rename from internal/constants/servers_test.go rename to internal/storage/hardcoded_test.go index 60c8c904..35798bea 100644 --- a/internal/constants/servers_test.go +++ b/internal/storage/hardcoded_test.go @@ -1,4 +1,4 @@ -package constants +package storage import ( "crypto/sha256" @@ -12,10 +12,10 @@ import ( "github.com/stretchr/testify/require" ) -func Test_parseAllServers(t *testing.T) { +func Test_parseHardcodedServers(t *testing.T) { t.Parallel() - servers, err := parseAllServers() + servers, err := parseHardcodedServers() require.NoError(t, err) require.NotEmpty(t, len(servers.Cyberghost.Servers)) @@ -38,7 +38,10 @@ func digestServerModelVersion(t *testing.T, server interface{}, version uint16) func Test_versions(t *testing.T) { t.Parallel() - allServers := GetAllServers() + + allServers, err := parseHardcodedServers() + require.NoError(t, err) + const format = "you forgot to update the version for %s" testCases := map[string]struct { model interface{} diff --git a/internal/storage/merge.go b/internal/storage/merge.go index b132406b..92072cc2 100644 --- a/internal/storage/merge.go +++ b/internal/storage/merge.go @@ -4,11 +4,10 @@ import ( "strconv" "time" - "github.com/qdm12/gluetun/internal/constants" "github.com/qdm12/gluetun/internal/models" ) -func (s *storage) logVersionDiff(provider string, diff int) { +func (s *Storage) logVersionDiff(provider string, diff int) { diffString := strconv.Itoa(diff) message := provider + " servers from file discarded because they are " + @@ -20,7 +19,7 @@ func (s *storage) logVersionDiff(provider string, diff int) { s.logger.Info(message) } -func (s *storage) logTimeDiff(provider string, persistedUnix, hardcodedUnix int64) { +func (s *Storage) logTimeDiff(provider string, persistedUnix, hardcodedUnix int64) { diff := time.Unix(persistedUnix, 0).Sub(time.Unix(hardcodedUnix, 0)) if diff < 0 { diff = -diff @@ -31,7 +30,7 @@ func (s *storage) logTimeDiff(provider string, persistedUnix, hardcodedUnix int6 s.logger.Info(message) } -func (s *storage) mergeServers(hardcoded, persisted models.AllServers) models.AllServers { +func (s *Storage) mergeServers(hardcoded, persisted models.AllServers) models.AllServers { return models.AllServers{ Version: hardcoded.Version, Cyberghost: s.mergeCyberghost(hardcoded.Cyberghost, persisted.Cyberghost), @@ -54,7 +53,7 @@ func (s *storage) mergeServers(hardcoded, persisted models.AllServers) models.Al } } -func (s *storage) mergeCyberghost(hardcoded, persisted models.CyberghostServers) models.CyberghostServers { +func (s *Storage) mergeCyberghost(hardcoded, persisted models.CyberghostServers) models.CyberghostServers { if persisted.Timestamp <= hardcoded.Timestamp { return hardcoded } @@ -69,7 +68,7 @@ func (s *storage) mergeCyberghost(hardcoded, persisted models.CyberghostServers) return persisted } -func (s *storage) mergeFastestvpn(hardcoded, persisted models.FastestvpnServers) models.FastestvpnServers { +func (s *Storage) mergeFastestvpn(hardcoded, persisted models.FastestvpnServers) models.FastestvpnServers { if persisted.Timestamp <= hardcoded.Timestamp { return hardcoded } @@ -82,7 +81,7 @@ func (s *storage) mergeFastestvpn(hardcoded, persisted models.FastestvpnServers) return persisted } -func (s *storage) mergeHideMyAss(hardcoded, persisted models.HideMyAssServers) models.HideMyAssServers { +func (s *Storage) mergeHideMyAss(hardcoded, persisted models.HideMyAssServers) models.HideMyAssServers { if persisted.Timestamp <= hardcoded.Timestamp { return hardcoded } @@ -95,7 +94,7 @@ func (s *storage) mergeHideMyAss(hardcoded, persisted models.HideMyAssServers) m return persisted } -func (s *storage) mergeIpvanish(hardcoded, persisted models.IpvanishServers) models.IpvanishServers { +func (s *Storage) mergeIpvanish(hardcoded, persisted models.IpvanishServers) models.IpvanishServers { if persisted.Timestamp <= hardcoded.Timestamp { return hardcoded } @@ -108,7 +107,7 @@ func (s *storage) mergeIpvanish(hardcoded, persisted models.IpvanishServers) mod return persisted } -func (s *storage) mergeIvpn(hardcoded, persisted models.IvpnServers) models.IvpnServers { +func (s *Storage) mergeIvpn(hardcoded, persisted models.IvpnServers) models.IvpnServers { if persisted.Timestamp <= hardcoded.Timestamp { return hardcoded } @@ -121,7 +120,7 @@ func (s *storage) mergeIvpn(hardcoded, persisted models.IvpnServers) models.Ivpn return persisted } -func (s *storage) mergeMullvad(hardcoded, persisted models.MullvadServers) models.MullvadServers { +func (s *Storage) mergeMullvad(hardcoded, persisted models.MullvadServers) models.MullvadServers { if persisted.Timestamp <= hardcoded.Timestamp { return hardcoded } @@ -136,7 +135,7 @@ func (s *storage) mergeMullvad(hardcoded, persisted models.MullvadServers) model return persisted } -func (s *storage) mergeNordVPN(hardcoded, persisted models.NordvpnServers) models.NordvpnServers { +func (s *Storage) mergeNordVPN(hardcoded, persisted models.NordvpnServers) models.NordvpnServers { if persisted.Timestamp <= hardcoded.Timestamp { return hardcoded } @@ -151,7 +150,7 @@ func (s *storage) mergeNordVPN(hardcoded, persisted models.NordvpnServers) model return persisted } -func (s *storage) mergePrivado(hardcoded, persisted models.PrivadoServers) models.PrivadoServers { +func (s *Storage) mergePrivado(hardcoded, persisted models.PrivadoServers) models.PrivadoServers { if persisted.Timestamp <= hardcoded.Timestamp { return hardcoded } @@ -165,7 +164,7 @@ func (s *storage) mergePrivado(hardcoded, persisted models.PrivadoServers) model return persisted } -func (s *storage) mergePIA(hardcoded, persisted models.PiaServers) models.PiaServers { +func (s *Storage) mergePIA(hardcoded, persisted models.PiaServers) models.PiaServers { if persisted.Timestamp <= hardcoded.Timestamp { return hardcoded } @@ -179,7 +178,7 @@ func (s *storage) mergePIA(hardcoded, persisted models.PiaServers) models.PiaSer return persisted } -func (s *storage) mergePrivatevpn(hardcoded, persisted models.PrivatevpnServers) models.PrivatevpnServers { +func (s *Storage) mergePrivatevpn(hardcoded, persisted models.PrivatevpnServers) models.PrivatevpnServers { if persisted.Timestamp <= hardcoded.Timestamp { return hardcoded } @@ -193,7 +192,7 @@ func (s *storage) mergePrivatevpn(hardcoded, persisted models.PrivatevpnServers) return persisted } -func (s *storage) mergeProtonvpn(hardcoded, persisted models.ProtonvpnServers) models.ProtonvpnServers { +func (s *Storage) mergeProtonvpn(hardcoded, persisted models.ProtonvpnServers) models.ProtonvpnServers { if persisted.Timestamp <= hardcoded.Timestamp { return hardcoded } @@ -207,7 +206,7 @@ func (s *storage) mergeProtonvpn(hardcoded, persisted models.ProtonvpnServers) m return persisted } -func (s *storage) mergePureVPN(hardcoded, persisted models.PurevpnServers) models.PurevpnServers { +func (s *Storage) mergePureVPN(hardcoded, persisted models.PurevpnServers) models.PurevpnServers { if persisted.Timestamp <= hardcoded.Timestamp { return hardcoded } @@ -222,7 +221,7 @@ func (s *storage) mergePureVPN(hardcoded, persisted models.PurevpnServers) model return persisted } -func (s *storage) mergeSurfshark(hardcoded, persisted models.SurfsharkServers) models.SurfsharkServers { +func (s *Storage) mergeSurfshark(hardcoded, persisted models.SurfsharkServers) models.SurfsharkServers { if persisted.Timestamp <= hardcoded.Timestamp { return hardcoded } @@ -237,7 +236,7 @@ func (s *storage) mergeSurfshark(hardcoded, persisted models.SurfsharkServers) m return persisted } -func (s *storage) mergeTorguard(hardcoded, persisted models.TorguardServers) models.TorguardServers { +func (s *Storage) mergeTorguard(hardcoded, persisted models.TorguardServers) models.TorguardServers { if persisted.Timestamp <= hardcoded.Timestamp { return hardcoded } @@ -251,21 +250,21 @@ func (s *storage) mergeTorguard(hardcoded, persisted models.TorguardServers) mod return persisted } -func (s *storage) mergeVPNUnlimited(hardcoded, persisted models.VPNUnlimitedServers) models.VPNUnlimitedServers { +func (s *Storage) mergeVPNUnlimited(hardcoded, persisted models.VPNUnlimitedServers) models.VPNUnlimitedServers { if persisted.Timestamp <= hardcoded.Timestamp { return hardcoded } versionDiff := int(hardcoded.Version) - int(persisted.Version) if versionDiff > 0 { - s.logVersionDiff(constants.VPNUnlimited, versionDiff) + s.logVersionDiff("VPN Unlimited", versionDiff) return hardcoded } - s.logTimeDiff(constants.VPNUnlimited, persisted.Timestamp, hardcoded.Timestamp) + s.logTimeDiff("VPN Unlimited", persisted.Timestamp, hardcoded.Timestamp) return persisted } -func (s *storage) mergeVyprvpn(hardcoded, persisted models.VyprvpnServers) models.VyprvpnServers { +func (s *Storage) mergeVyprvpn(hardcoded, persisted models.VyprvpnServers) models.VyprvpnServers { if persisted.Timestamp <= hardcoded.Timestamp { return hardcoded } @@ -280,7 +279,7 @@ func (s *storage) mergeVyprvpn(hardcoded, persisted models.VyprvpnServers) model return persisted } -func (s *storage) mergeWindscribe(hardcoded, persisted models.WindscribeServers) models.WindscribeServers { +func (s *Storage) mergeWindscribe(hardcoded, persisted models.WindscribeServers) models.WindscribeServers { if persisted.Timestamp <= hardcoded.Timestamp { return hardcoded } diff --git a/internal/storage/read.go b/internal/storage/read.go new file mode 100644 index 00000000..6ff80055 --- /dev/null +++ b/internal/storage/read.go @@ -0,0 +1,28 @@ +package storage + +import ( + "encoding/json" + "errors" + "io" + "os" + + "github.com/qdm12/gluetun/internal/models" +) + +func readFromFile(filepath string) (servers models.AllServers, err error) { + file, err := os.Open(filepath) + if os.IsNotExist(err) { + return servers, nil + } else if err != nil { + return servers, err + } + decoder := json.NewDecoder(file) + if err := decoder.Decode(&servers); err != nil { + _ = file.Close() + if errors.Is(err, io.EOF) { + return servers, nil + } + return servers, err + } + return servers, file.Close() +} diff --git a/internal/storage/servers.go b/internal/storage/servers.go new file mode 100644 index 00000000..0830777c --- /dev/null +++ b/internal/storage/servers.go @@ -0,0 +1,7 @@ +package storage + +import "github.com/qdm12/gluetun/internal/models" + +func (s *Storage) GetServers() models.AllServers { + return s.mergedServers.GetCopy() +} diff --git a/internal/constants/servers.json b/internal/storage/servers.json similarity index 100% rename from internal/constants/servers.json rename to internal/storage/servers.json diff --git a/internal/storage/storage.go b/internal/storage/storage.go index 574aa236..4bf90ec2 100644 --- a/internal/storage/storage.go +++ b/internal/storage/storage.go @@ -6,20 +6,29 @@ import ( "github.com/qdm12/golibs/logging" ) -type Storage interface { - // Passing an empty filepath disables writing to a file - SyncServers(hardcodedServers models.AllServers) (allServers models.AllServers, err error) - FlushToFile(servers models.AllServers) error +type Storage struct { + mergedServers models.AllServers + hardcodedServers models.AllServers + logger logging.Logger + filepath string } -type storage struct { - logger logging.Logger - filepath string -} +// New creates a new storage and reads the servers from the +// embedded servers file and the file on disk. +// Passing an empty filepath disables writing servers to a file. +func New(logger logging.Logger, filepath string) (storage *Storage, err error) { + // error returned covered by unit test + harcodedServers, _ := parseHardcodedServers() -func New(logger logging.Logger, filepath string) Storage { - return &storage{ - logger: logger, - filepath: filepath, + storage = &Storage{ + hardcodedServers: harcodedServers, + logger: logger, + filepath: filepath, } + + if err := storage.SyncServers(); err != nil { + return nil, err + } + + return storage, nil } diff --git a/internal/storage/sync.go b/internal/storage/sync.go index 301c30e6..e849e3cd 100644 --- a/internal/storage/sync.go +++ b/internal/storage/sync.go @@ -1,14 +1,9 @@ package storage import ( - "encoding/json" "errors" "fmt" - "io" - "os" - "path/filepath" "reflect" - "strconv" "github.com/qdm12/gluetun/internal/models" ) @@ -38,70 +33,35 @@ func countServers(allServers models.AllServers) int { len(allServers.Windscribe.Servers) } -func (s *storage) SyncServers(hardcodedServers models.AllServers) ( - allServers models.AllServers, err error) { +func (s *Storage) SyncServers() (err error) { serversOnFile, err := readFromFile(s.filepath) if err != nil { - return allServers, fmt.Errorf("%w: %s", ErrCannotReadFile, err) + return fmt.Errorf("%w: %s", ErrCannotReadFile, err) } - hardcodedCount := countServers(hardcodedServers) + hardcodedCount := countServers(s.hardcodedServers) countOnFile := countServers(serversOnFile) if countOnFile == 0 { - s.logger.Info("creating " + s.filepath + " with " + strconv.Itoa(hardcodedCount) + " hardcoded servers") - allServers = hardcodedServers + s.logger.Info(fmt.Sprintf( + "creating %s with %d hardcoded servers", + s.filepath, hardcodedCount)) + s.mergedServers = s.hardcodedServers } else { - s.logger.Info("merging by most recent " + - strconv.Itoa(hardcodedCount) + " hardcoded servers and " + - strconv.Itoa(countOnFile) + " servers read from " + s.filepath) - allServers = s.mergeServers(hardcodedServers, serversOnFile) + s.logger.Info(fmt.Sprintf( + "merging by most recent %d hardcoded servers and %d servers read from %s", + hardcodedCount, countOnFile, s.filepath)) + + s.mergedServers = s.mergeServers(s.hardcodedServers, serversOnFile) } // Eventually write file - if s.filepath == "" || reflect.DeepEqual(serversOnFile, allServers) { - return allServers, nil + if s.filepath == "" || reflect.DeepEqual(serversOnFile, s.mergedServers) { + return nil } - if err := flushToFile(s.filepath, allServers); err != nil { - return allServers, fmt.Errorf("%w: %s", ErrCannotWriteFile, err) + if err := flushToFile(s.filepath, s.mergedServers); err != nil { + return fmt.Errorf("%w: %s", ErrCannotWriteFile, err) } - return allServers, nil -} - -func readFromFile(filepath string) (servers models.AllServers, err error) { - file, err := os.Open(filepath) - if os.IsNotExist(err) { - return servers, nil - } else if err != nil { - return servers, err - } - decoder := json.NewDecoder(file) - if err := decoder.Decode(&servers); err != nil { - _ = file.Close() - if errors.Is(err, io.EOF) { - return servers, nil - } - return servers, err - } - return servers, file.Close() -} - -func flushToFile(path string, servers models.AllServers) error { - dirPath := filepath.Dir(path) - if err := os.MkdirAll(dirPath, 0644); err != nil { - return err - } - - file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) - if err != nil { - return err - } - encoder := json.NewEncoder(file) - encoder.SetIndent("", " ") - if err := encoder.Encode(servers); err != nil { - _ = file.Close() - return err - } - return file.Close() + return nil } diff --git a/internal/updater/loop.go b/internal/updater/loop.go index 4f8f8414..8cd67295 100644 --- a/internal/updater/loop.go +++ b/internal/updater/loop.go @@ -27,7 +27,7 @@ type looper struct { state state // Objects updater Updater - storage storage.Storage + flusher storage.Flusher setAllServers func(allServers models.AllServers) logger logging.Logger // Internal channels and locks @@ -46,7 +46,7 @@ type looper struct { const defaultBackoffTime = 5 * time.Second func NewLooper(settings configuration.Updater, currentServers models.AllServers, - storage storage.Storage, setAllServers func(allServers models.AllServers), + flusher storage.Flusher, setAllServers func(allServers models.AllServers), client *http.Client, logger logging.Logger) Looper { return &looper{ state: state{ @@ -54,7 +54,7 @@ func NewLooper(settings configuration.Updater, currentServers models.AllServers, settings: settings, }, updater: New(settings, client, currentServers, logger), - storage: storage, + flusher: flusher, setAllServers: setAllServers, logger: logger, start: make(chan struct{}), @@ -140,7 +140,7 @@ func (l *looper) Run(ctx context.Context, done chan<- struct{}) { l.stopped <- struct{}{} case servers := <-serversCh: l.setAllServers(servers) - if err := l.storage.FlushToFile(servers); err != nil { + if err := l.flusher.FlushToFile(servers); err != nil { l.logger.Error(err.Error()) } runWg.Wait()