Multi options filters, fixes #231 (#262)

* OWNED environment variable for Mullvad
* CSV are now accepted for all servers filtering environment variables
This commit is contained in:
Quentin McGaw
2020-10-18 17:15:42 -04:00
committed by GitHub
parent c932f48a95
commit af606463ea
26 changed files with 247 additions and 223 deletions

View File

@@ -61,6 +61,7 @@ ENV VPNSP=pia \
CITY= \ CITY= \
# Mullvad only # Mullvad only
ISP= \ ISP= \
OWNED=no \
# Mullvad and Windscribe only # Mullvad and Windscribe only
PORT= \ PORT= \
# Cyberghost only # Cyberghost only

View File

@@ -91,6 +91,8 @@ docker run --rm --network=container:gluetun alpine:3.12 wget -qO- https://ipinfo
**TLDR**; only set the 🏁 marked environment variables to get started. **TLDR**; only set the 🏁 marked environment variables to get started.
💡 For all server filtering options such as `REGION`, you can have multiple values separated by a comma, i.e. `Germany,Singapore`
### VPN ### VPN
| Variable | Default | Choices | Description | | Variable | Default | Choices | Description |
@@ -127,6 +129,7 @@ docker run --rm --network=container:gluetun alpine:3.12 wget -qO- https://ipinfo
| `CITY` | | One of the [Mullvad cities](https://mullvad.net/en/servers/#openvpn) | VPN server city | | `CITY` | | One of the [Mullvad cities](https://mullvad.net/en/servers/#openvpn) | VPN server city |
| `ISP` | | One of the [Mullvad ISP](https://mullvad.net/en/servers/#openvpn) | VPN server ISP | | `ISP` | | One of the [Mullvad ISP](https://mullvad.net/en/servers/#openvpn) | VPN server ISP |
| `PORT` | | `80`, `443` or `1401` for TCP; `53`, `1194`, `1195`, `1196`, `1197`, `1300`, `1301`, `1302`, `1303` or `1400` for UDP. Defaults to TCP `443` and UDP `1194` | Custom VPN port to use | | `PORT` | | `80`, `443` or `1401` for TCP; `53`, `1194`, `1195`, `1196`, `1197`, `1300`, `1301`, `1302`, `1303` or `1400` for UDP. Defaults to TCP `443` and UDP `1194` | Custom VPN port to use |
| `OWNED` | `no` | `yes` or `no` | If the VPN server is owned by Mullvad |
💡 [Mullvad IPv6 Wiki page](https://github.com/qdm12/gluetun/wiki/Mullvad-IPv6) 💡 [Mullvad IPv6 Wiki page](https://github.com/qdm12/gluetun/wiki/Mullvad-IPv6)

4
go.mod
View File

@@ -6,9 +6,9 @@ require (
github.com/fatih/color v1.9.0 github.com/fatih/color v1.9.0
github.com/golang/mock v1.4.4 github.com/golang/mock v1.4.4
github.com/kyokomi/emoji v2.2.4+incompatible github.com/kyokomi/emoji v2.2.4+incompatible
github.com/qdm12/golibs v0.0.0-20201018021451-d64f6f83fb81 github.com/qdm12/golibs v0.0.0-20201018204514-1d5986880422
github.com/qdm12/ss-server v0.0.0-20200819124651-6428e626ee83 github.com/qdm12/ss-server v0.0.0-20200819124651-6428e626ee83
github.com/stretchr/testify v1.6.1 github.com/stretchr/testify v1.6.1
golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0 golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0
golang.org/x/sys v0.0.0-20201017003518-b09fb700fbb7 golang.org/x/sys v0.0.0-20201018121011-98379d014ca7
) )

12
go.sum
View File

@@ -72,10 +72,8 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/qdm12/golibs v0.0.0-20201018021451-d64f6f83fb81 h1:UouAegRn1ZB2BgoA7cA6wE5hr24cN2mgo4Lo8qC9yxo= github.com/qdm12/golibs v0.0.0-20201018204514-1d5986880422 h1:sk+ri/MsgwBqpN3MqOazV8itCid7F2wGS8PbG1kWg9o=
github.com/qdm12/golibs v0.0.0-20201018021451-d64f6f83fb81/go.mod h1:xbNrWrKyAZ5akH7lqp/uEA2HTZg+qDOzzugSiyLbzAA= github.com/qdm12/golibs v0.0.0-20201018204514-1d5986880422/go.mod h1:pikkTN7g7zRuuAnERwqW1yAFq6pYmxrxpjiwGvb0Ysc=
github.com/qdm12/ss-server v0.0.0-20200819005413-6b516c299307 h1:+LhVxIKpZgUM8ZcopIuc3Yjk+p76dWRdYLQiAA7caZM=
github.com/qdm12/ss-server v0.0.0-20200819005413-6b516c299307/go.mod h1:ABVUkxubboL3vqBkOwDV9glX1/x7SnYrckBe5d+M/zw=
github.com/qdm12/ss-server v0.0.0-20200819124651-6428e626ee83 h1:b7sNsgsKxH0mbl9L1hdUp5KSDkZ/1kOQ+iHiBVgFElM= github.com/qdm12/ss-server v0.0.0-20200819124651-6428e626ee83 h1:b7sNsgsKxH0mbl9L1hdUp5KSDkZ/1kOQ+iHiBVgFElM=
github.com/qdm12/ss-server v0.0.0-20200819124651-6428e626ee83/go.mod h1:ABVUkxubboL3vqBkOwDV9glX1/x7SnYrckBe5d+M/zw= github.com/qdm12/ss-server v0.0.0-20200819124651-6428e626ee83/go.mod h1:ABVUkxubboL3vqBkOwDV9glX1/x7SnYrckBe5d+M/zw=
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
@@ -119,11 +117,9 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed h1:J22ig1FUekjjkmZUM7pTKixYm8DvrYsvrBZdunYeIuQ=
golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201017003518-b09fb700fbb7 h1:XtNJkfEjb4zR3q20BBBcYUykVOEMgZeIUOpBPfNYgxg= golang.org/x/sys v0.0.0-20201018121011-98379d014ca7 h1:CNOpL+H7PSxBI7dF/EIUsfOguRSzWp6CQ91yxZE6PG4=
golang.org/x/sys v0.0.0-20201017003518-b09fb700fbb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201018121011-98379d014ca7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@@ -20,24 +20,24 @@ type ServerSelection struct { //nolint:maligned
TargetIP net.IP `json:"targetIP,omitempty"` TargetIP net.IP `json:"targetIP,omitempty"`
// Cyberghost, PIA, Surfshark, Windscribe, Vyprvpn, NordVPN // Cyberghost, PIA, Surfshark, Windscribe, Vyprvpn, NordVPN
Region string `json:"region"` Regions []string `json:"regions"`
// Cyberghost // Cyberghost
Group string `json:"group"` Group string `json:"group"`
// Mullvad, PureVPN // Mullvad, PureVPN
Country string `json:"country"` Countries []string `json:"countries"`
City string `json:"city"` Cities []string `json:"cities"`
// Mullvad // Mullvad
ISP string `json:"isp"` ISPs []string `json:"isps"`
Owned bool `json:"owned"` Owned bool `json:"owned"`
// Mullvad, Windscribe // Mullvad, Windscribe
CustomPort uint16 `json:"customPort"` CustomPort uint16 `json:"customPort"`
// NordVPN // NordVPN
Number uint16 `json:"number"` Numbers []uint16 `json:"numbers"`
// PIA // PIA
EncryptionPreset string `json:"encryptionPreset"` EncryptionPreset string `json:"encryptionPreset"`
@@ -71,9 +71,9 @@ func (p *ProviderSettings) String() string {
if p.ServerSelection.CustomPort > 0 { if p.ServerSelection.CustomPort > 0 {
customPort = fmt.Sprintf("%d", p.ServerSelection.CustomPort) customPort = fmt.Sprintf("%d", p.ServerSelection.CustomPort)
} }
number := "" numbers := make([]string, len(p.ServerSelection.Numbers))
if p.ServerSelection.Number > 0 { for i, number := range p.ServerSelection.Numbers {
number = fmt.Sprintf("%d", p.ServerSelection.Number) numbers[i] = fmt.Sprintf("%d", number)
} }
ipv6 := "off" ipv6 := "off"
if p.ExtraConfigOptions.OpenVPNIPv6 { if p.ExtraConfigOptions.OpenVPNIPv6 {
@@ -82,53 +82,53 @@ func (p *ProviderSettings) String() string {
switch strings.ToLower(string(p.Name)) { switch strings.ToLower(string(p.Name)) {
case "private internet access old": case "private internet access old":
settingsList = append(settingsList, settingsList = append(settingsList,
"Region: "+p.ServerSelection.Region, "Regions: "+commaJoin(p.ServerSelection.Regions),
"Encryption preset: "+p.ExtraConfigOptions.EncryptionPreset, "Encryption preset: "+p.ExtraConfigOptions.EncryptionPreset,
"Port forwarding: "+p.PortForwarding.String(), "Port forwarding: "+p.PortForwarding.String(),
) )
case "private internet access": case "private internet access":
settingsList = append(settingsList, settingsList = append(settingsList,
"Region: "+p.ServerSelection.Region, "Regions: "+commaJoin(p.ServerSelection.Regions),
"Encryption preset: "+p.ExtraConfigOptions.EncryptionPreset, "Encryption preset: "+p.ExtraConfigOptions.EncryptionPreset,
"Port forwarding: "+p.PortForwarding.String(), "Port forwarding: "+p.PortForwarding.String(),
) )
case "mullvad": case "mullvad":
settingsList = append(settingsList, settingsList = append(settingsList,
"Country: "+p.ServerSelection.Country, "Countries: "+commaJoin(p.ServerSelection.Countries),
"City: "+p.ServerSelection.City, "Cities: "+commaJoin(p.ServerSelection.Cities),
"ISP: "+p.ServerSelection.ISP, "ISPs: "+commaJoin(p.ServerSelection.ISPs),
"Custom port: "+customPort, "Custom port: "+customPort,
"IPv6: "+ipv6, "IPv6: "+ipv6,
) )
case "windscribe": case "windscribe":
settingsList = append(settingsList, settingsList = append(settingsList,
"Region: "+p.ServerSelection.Region, "Regions: "+commaJoin(p.ServerSelection.Regions),
"Custom port: "+customPort, "Custom port: "+customPort,
) )
case "surfshark": case "surfshark":
settingsList = append(settingsList, settingsList = append(settingsList,
"Region: "+p.ServerSelection.Region, "Regions: "+commaJoin(p.ServerSelection.Regions),
) )
case "cyberghost": case "cyberghost":
settingsList = append(settingsList, settingsList = append(settingsList,
"ClientKey: [redacted]", "ClientKey: [redacted]",
"Group: "+p.ServerSelection.Group, "Group: "+p.ServerSelection.Group,
"Region: "+p.ServerSelection.Region, "Regions: "+commaJoin(p.ServerSelection.Regions),
) )
case "vyprvpn": case "vyprvpn":
settingsList = append(settingsList, settingsList = append(settingsList,
"Region: "+p.ServerSelection.Region, "Regions: "+commaJoin(p.ServerSelection.Regions),
) )
case "nordvpn": case "nordvpn":
settingsList = append(settingsList, settingsList = append(settingsList,
"Region: "+p.ServerSelection.Region, "Regions: "+commaJoin(p.ServerSelection.Regions),
"Number: "+number, "Numbers: "+commaJoin(numbers),
) )
case "purevpn": case "purevpn":
settingsList = append(settingsList, settingsList = append(settingsList,
"Region: "+p.ServerSelection.Region, "Regions: "+commaJoin(p.ServerSelection.Regions),
"Country: "+p.ServerSelection.Country, "Countries: "+commaJoin(p.ServerSelection.Countries),
"City: "+p.ServerSelection.City, "Cities: "+commaJoin(p.ServerSelection.Cities),
) )
default: default:
settingsList = append(settingsList, settingsList = append(settingsList,
@@ -142,3 +142,7 @@ func (p *ProviderSettings) String() string {
} }
return strings.Join(settingsList, "\n |--") return strings.Join(settingsList, "\n |--")
} }
func commaJoin(slice []string) string {
return strings.Join(slice, ", ")
}

View File

@@ -14,12 +14,11 @@ func (p *reader) GetCyberghostGroup() (group string, err error) {
return s, err return s, err
} }
// GetCyberghostRegion obtains the country name for the Cyberghost server from the // GetCyberghostRegions obtains the country names for the Cyberghost servers from the
// environment variable REGION // environment variable REGION
func (p *reader) GetCyberghostRegion() (region string, err error) { func (p *reader) GetCyberghostRegions() (regions []string, err error) {
choices := append(constants.CyberghostRegionChoices(), "") choices := append(constants.CyberghostRegionChoices(), "")
s, err := p.envParams.GetValueIfInside("REGION", choices) return p.envParams.GetCSVInPossibilities("REGION", choices)
return s, err
} }
// GetCyberghostClientKey obtains the one line client key to use for openvpn from the // GetCyberghostClientKey obtains the one line client key to use for openvpn from the

View File

@@ -5,25 +5,25 @@ import (
libparams "github.com/qdm12/golibs/params" libparams "github.com/qdm12/golibs/params"
) )
// GetMullvadCountry obtains the country for the Mullvad server from the // GetMullvadCountries obtains the countries for the Mullvad servers from the
// environment variable COUNTRY // environment variable COUNTRY
func (r *reader) GetMullvadCountry() (country string, err error) { func (r *reader) GetMullvadCountries() (countries []string, err error) {
choices := append(constants.MullvadCountryChoices(), "") choices := append(constants.MullvadCountryChoices(), "")
return r.envParams.GetValueIfInside("COUNTRY", choices) return r.envParams.GetCSVInPossibilities("COUNTRY", choices)
} }
// GetMullvadCity obtains the city for the Mullvad server from the // GetMullvadCity obtains the cities for the Mullvad servers from the
// environment variable CITY // environment variable CITY
func (r *reader) GetMullvadCity() (country string, err error) { func (r *reader) GetMullvadCities() (cities []string, err error) {
choices := append(constants.MullvadCityChoices(), "") choices := append(constants.MullvadCityChoices(), "")
return r.envParams.GetValueIfInside("CITY", choices) return r.envParams.GetCSVInPossibilities("CITY", choices)
} }
// GetMullvadISP obtains the ISP for the Mullvad server from the // GetMullvadISPs obtains the ISPs for the Mullvad servers from the
// environment variable ISP // environment variable ISP
func (r *reader) GetMullvadISP() (isp string, err error) { func (r *reader) GetMullvadISPs() (isps []string, err error) {
choices := append(constants.MullvadISPChoices(), "") choices := append(constants.MullvadISPChoices(), "")
return r.envParams.GetValueIfInside("ISP", choices) return r.envParams.GetCSVInPossibilities("ISP", choices)
} }
// GetMullvadPort obtains the port to reach the Mullvad server on from the // GetMullvadPort obtains the port to reach the Mullvad server on from the
@@ -32,3 +32,9 @@ func (r *reader) GetMullvadPort() (port uint16, err error) {
n, err := r.envParams.GetEnvIntRange("PORT", 0, 65535, libparams.Default("0")) n, err := r.envParams.GetEnvIntRange("PORT", 0, 65535, libparams.Default("0"))
return uint16(n), err return uint16(n), err
} }
// GetMullvadOwned obtains if the server should be owned by Mullvad or not from the
// environment variable OWNED
func (r *reader) GetMullvadOwned() (owned bool, err error) {
return r.envParams.GetYesNo("OWNED", libparams.Default("no"))
}

View File

@@ -1,23 +1,37 @@
package params package params
import ( import (
"fmt"
"strconv"
"github.com/qdm12/gluetun/internal/constants" "github.com/qdm12/gluetun/internal/constants"
libparams "github.com/qdm12/golibs/params"
) )
// GetNordvpnRegion obtains the region (country) for the NordVPN server from the // GetNordvpnRegions obtains the regions (countries) for the NordVPN server from the
// environment variable REGION // environment variable REGION
func (r *reader) GetNordvpnRegion() (region string, err error) { func (r *reader) GetNordvpnRegions() (regions []string, err error) {
choices := append(constants.NordvpnRegionChoices(), "") choices := append(constants.NordvpnRegionChoices(), "")
return r.envParams.GetValueIfInside("REGION", choices) return r.envParams.GetCSVInPossibilities("REGION", choices)
} }
// GetNordvpnRegion obtains the server number (optional) for the NordVPN server from the // GetNordvpnRegion obtains the server numbers (optional) for the NordVPN servers from the
// environment variable SERVER_NUMBER // environment variable SERVER_NUMBER
func (r *reader) GetNordvpnNumber() (number uint16, err error) { func (r *reader) GetNordvpnNumbers() (numbers []uint16, err error) {
n, err := r.envParams.GetEnvIntRange("SERVER_NUMBER", 0, 65535, libparams.Default("0")) possibilities := make([]string, 65536)
if err != nil { for i := range possibilities {
return 0, err possibilities[i] = fmt.Sprintf("%d", i)
} }
return uint16(n), nil values, err := r.envParams.GetCSVInPossibilities("SERVER_NUMBER", possibilities)
if err != nil {
return nil, err
}
numbers = make([]uint16, len(values))
for i := range values {
n, err := strconv.Atoi(values[i])
if err != nil {
return nil, err
}
numbers[i] = uint16(n)
}
return numbers, nil
} }

View File

@@ -61,38 +61,39 @@ type Reader interface {
GetPortForwarding() (activated bool, err error) GetPortForwarding() (activated bool, err error)
GetPortForwardingStatusFilepath() (filepath models.Filepath, err error) GetPortForwardingStatusFilepath() (filepath models.Filepath, err error)
GetPIAEncryptionPreset() (preset string, err error) GetPIAEncryptionPreset() (preset string, err error)
GetPIARegion() (region string, err error) GetPIARegions() (regions []string, err error)
GetPIAOldRegion() (region string, err error) GetPIAOldRegions() (regions []string, err error)
// Mullvad getters // Mullvad getters
GetMullvadCountry() (country string, err error) GetMullvadCountries() (countries []string, err error)
GetMullvadCity() (country string, err error) GetMullvadCities() (cities []string, err error)
GetMullvadISP() (country string, err error) GetMullvadISPs() (ips []string, err error)
GetMullvadPort() (port uint16, err error) GetMullvadPort() (port uint16, err error)
GetMullvadOwned() (owned bool, err error)
// Windscribe getters // Windscribe getters
GetWindscribeRegion() (country string, err error) GetWindscribeRegions() (countries []string, err error)
GetWindscribePort(protocol models.NetworkProtocol) (port uint16, err error) GetWindscribePort(protocol models.NetworkProtocol) (port uint16, err error)
// Surfshark getters // Surfshark getters
GetSurfsharkRegion() (country string, err error) GetSurfsharkRegions() (countries []string, err error)
// Cyberghost getters // Cyberghost getters
GetCyberghostGroup() (group string, err error) GetCyberghostGroup() (group string, err error)
GetCyberghostRegion() (region string, err error) GetCyberghostRegions() (regions []string, err error)
GetCyberghostClientKey() (clientKey string, err error) GetCyberghostClientKey() (clientKey string, err error)
// Vyprvpn getters // Vyprvpn getters
GetVyprvpnRegion() (region string, err error) GetVyprvpnRegions() (regions []string, err error)
// NordVPN getters // NordVPN getters
GetNordvpnRegion() (region string, err error) GetNordvpnRegions() (regions []string, err error)
GetNordvpnNumber() (number uint16, err error) GetNordvpnNumbers() (numbers []uint16, err error)
// PureVPN getters // PureVPN getters
GetPurevpnRegion() (region string, err error) GetPurevpnRegions() (regions []string, err error)
GetPurevpnCountry() (country string, err error) GetPurevpnCountries() (countries []string, err error)
GetPurevpnCity() (city string, err error) GetPurevpnCities() (cities []string, err error)
// Shadowsocks getters // Shadowsocks getters
GetShadowSocks() (activated bool, err error) GetShadowSocks() (activated bool, err error)

View File

@@ -56,16 +56,16 @@ func (r *reader) GetPIAEncryptionPreset() (preset string, err error) {
libparams.Default(constants.PIAEncryptionPresetStrong)) libparams.Default(constants.PIAEncryptionPresetStrong))
} }
// GetPIARegion obtains the region for the PIA server from the // GetPIARegions obtains the regions for the PIA servers from the
// environment variable REGION // environment variable REGION
func (r *reader) GetPIARegion() (region string, err error) { func (r *reader) GetPIARegions() (regions []string, err error) {
choices := append(constants.PIAGeoChoices(), "") choices := append(constants.PIAGeoChoices(), "")
return r.envParams.GetValueIfInside("REGION", choices) return r.envParams.GetCSVInPossibilities("REGION", choices)
} }
// GetPIAOldRegion obtains the region for the PIA server from the // GetPIAOldRegions obtains the regions for the PIA servers from the
// environment variable REGION // environment variable REGION
func (r *reader) GetPIAOldRegion() (region string, err error) { func (r *reader) GetPIAOldRegions() (regions []string, err error) {
choices := append(constants.PIAOldGeoChoices(), "") choices := append(constants.PIAOldGeoChoices(), "")
return r.envParams.GetValueIfInside("REGION", choices) return r.envParams.GetCSVInPossibilities("REGION", choices)
} }

View File

@@ -4,23 +4,23 @@ import (
"github.com/qdm12/gluetun/internal/constants" "github.com/qdm12/gluetun/internal/constants"
) )
// GetPurevpnRegion obtains the region (continent) for the PureVPN server from the // GetPurevpnRegions obtains the regions (continents) for the PureVPN servers from the
// environment variable REGION // environment variable REGION
func (r *reader) GetPurevpnRegion() (region string, err error) { func (r *reader) GetPurevpnRegions() (regions []string, err error) {
choices := append(constants.PurevpnRegionChoices(), "") choices := append(constants.PurevpnRegionChoices(), "")
return r.envParams.GetValueIfInside("REGION", choices) return r.envParams.GetCSVInPossibilities("REGION", choices)
} }
// GetPurevpnCountry obtains the country for the PureVPN server from the // GetPurevpnCountries obtains the countries for the PureVPN servers from the
// environment variable COUNTRY // environment variable COUNTRY
func (r *reader) GetPurevpnCountry() (country string, err error) { func (r *reader) GetPurevpnCountries() (countries []string, err error) {
choices := append(constants.PurevpnCountryChoices(), "") choices := append(constants.PurevpnCountryChoices(), "")
return r.envParams.GetValueIfInside("COUNTRY", choices) return r.envParams.GetCSVInPossibilities("COUNTRY", choices)
} }
// GetPurevpnCity obtains the city for the PureVPN server from the // GetPurevpnCities obtains the cities for the PureVPN servers from the
// environment variable CITY // environment variable CITY
func (r *reader) GetPurevpnCity() (city string, err error) { func (r *reader) GetPurevpnCities() (cities []string, err error) {
choices := append(constants.PurevpnCityChoices(), "") choices := append(constants.PurevpnCityChoices(), "")
return r.envParams.GetValueIfInside("CITY", choices) return r.envParams.GetCSVInPossibilities("CITY", choices)
} }

View File

@@ -4,9 +4,9 @@ import (
"github.com/qdm12/gluetun/internal/constants" "github.com/qdm12/gluetun/internal/constants"
) )
// GetSurfsharkRegion obtains the region for the Surfshark server from the // GetSurfsharkRegions obtains the regions for the Surfshark servers from the
// environment variable REGION // environment variable REGION
func (r *reader) GetSurfsharkRegion() (region string, err error) { func (r *reader) GetSurfsharkRegions() (regions []string, err error) {
choices := append(constants.SurfsharkRegionChoices(), "") choices := append(constants.SurfsharkRegionChoices(), "")
return r.envParams.GetValueIfInside("REGION", choices) return r.envParams.GetCSVInPossibilities("REGION", choices)
} }

View File

@@ -4,9 +4,9 @@ import (
"github.com/qdm12/gluetun/internal/constants" "github.com/qdm12/gluetun/internal/constants"
) )
// GetVyprvpnRegion obtains the region for the Vyprvpn server from the // GetVyprvpnRegions obtains the regions for the Vyprvpn servers from the
// environment variable REGION // environment variable REGION
func (r *reader) GetVyprvpnRegion() (region string, err error) { func (r *reader) GetVyprvpnRegions() (regions []string, err error) {
choices := append(constants.VyprvpnRegionChoices(), "") choices := append(constants.VyprvpnRegionChoices(), "")
return r.envParams.GetValueIfInside("REGION", choices) return r.envParams.GetCSVInPossibilities("REGION", choices)
} }

View File

@@ -8,11 +8,11 @@ import (
libparams "github.com/qdm12/golibs/params" libparams "github.com/qdm12/golibs/params"
) )
// GetWindscribeRegion obtains the region for the Windscribe server from the // GetWindscribeRegions obtains the regions for the Windscribe servers from the
// environment variable REGION // environment variable REGION
func (r *reader) GetWindscribeRegion() (region string, err error) { func (r *reader) GetWindscribeRegions() (regions []string, err error) {
choices := append(constants.WindscribeRegionChoices(), "") choices := append(constants.WindscribeRegionChoices(), "")
return r.envParams.GetValueIfInside("REGION", choices) return r.envParams.GetCSVInPossibilities("REGION", choices)
} }
// GetMullvadPort obtains the port to reach the Mullvad server on from the // GetMullvadPort obtains the port to reach the Mullvad server on from the

View File

@@ -27,16 +27,13 @@ func newCyberghost(servers []models.CyberghostServer, timeNow timeNowFunc) *cybe
} }
} }
func (c *cyberghost) filterServers(region, group string) (servers []models.CyberghostServer) { func (c *cyberghost) filterServers(regions []string, group string) (servers []models.CyberghostServer) {
for i, server := range c.servers { for _, server := range c.servers {
if len(region) == 0 { switch {
server.Region = "" case len(group) > 0 && group != server.Group,
} filterByPossibilities(server.Region, regions):
if len(group) == 0 { default:
server.Group = "" servers = append(servers, server)
}
if strings.EqualFold(server.Region, region) && strings.EqualFold(server.Group, group) {
servers = append(servers, c.servers[i])
} }
} }
return servers return servers
@@ -47,9 +44,9 @@ func (c *cyberghost) GetOpenVPNConnection(selection models.ServerSelection) (con
return models.OpenVPNConnection{IP: selection.TargetIP, Port: 443, Protocol: selection.Protocol}, nil return models.OpenVPNConnection{IP: selection.TargetIP, Port: 443, Protocol: selection.Protocol}, nil
} }
servers := c.filterServers(selection.Region, selection.Group) servers := c.filterServers(selection.Regions, selection.Group)
if len(servers) == 0 { if len(servers) == 0 {
return connection, fmt.Errorf("no server found for region %q and group %q", selection.Region, selection.Group) return connection, fmt.Errorf("no server found for regions %s and group %q", commaJoin(selection.Regions), selection.Group)
} }
var connections []models.OpenVPNConnection var connections []models.OpenVPNConnection

View File

@@ -6,7 +6,6 @@ import (
"math/rand" "math/rand"
"net" "net"
"net/http" "net/http"
"strings"
"github.com/qdm12/gluetun/internal/constants" "github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/firewall" "github.com/qdm12/gluetun/internal/firewall"
@@ -27,21 +26,16 @@ func newMullvad(servers []models.MullvadServer, timeNow timeNowFunc) *mullvad {
} }
} }
func (m *mullvad) filterServers(country, city, isp string) (servers []models.MullvadServer) { func (m *mullvad) filterServers(countries, cities, isps []string, owned bool) (servers []models.MullvadServer) {
for i, server := range m.servers { for _, server := range m.servers {
if len(country) == 0 { switch {
server.Country = "" case
} filterByPossibilities(server.Country, countries),
if len(city) == 0 { filterByPossibilities(server.City, cities),
server.City = "" filterByPossibilities(server.ISP, isps),
} owned && !server.Owned:
if len(isp) == 0 { default:
server.ISP = "" servers = append(servers, server)
}
if strings.EqualFold(server.Country, country) &&
strings.EqualFold(server.City, city) &&
strings.EqualFold(server.ISP, isp) {
servers = append(servers, m.servers[i])
} }
} }
return servers return servers
@@ -61,9 +55,10 @@ func (m *mullvad) GetOpenVPNConnection(selection models.ServerSelection) (connec
return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil
} }
servers := m.filterServers(selection.Country, selection.City, selection.ISP) servers := m.filterServers(selection.Countries, selection.Cities, selection.ISPs, selection.Owned)
if len(servers) == 0 { if len(servers) == 0 {
return connection, fmt.Errorf("no server found for country %q, city %q and ISP %q", selection.Country, selection.City, selection.ISP) return connection, fmt.Errorf("no server found for countries %s, cities %s, ISPs %s and owned %t",
commaJoin(selection.Countries), commaJoin(selection.Cities), commaJoin(selection.ISPs), selection.Owned)
} }
var connections []models.OpenVPNConnection var connections []models.OpenVPNConnection

View File

@@ -6,7 +6,6 @@ import (
"math/rand" "math/rand"
"net" "net"
"net/http" "net/http"
"strings"
"github.com/qdm12/gluetun/internal/constants" "github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/firewall" "github.com/qdm12/gluetun/internal/firewall"
@@ -27,22 +26,21 @@ func newNordvpn(servers []models.NordvpnServer, timeNow timeNowFunc) *nordvpn {
} }
} }
func (n *nordvpn) filterServers(region string, protocol models.NetworkProtocol, number uint16) (servers []models.NordvpnServer) { func (n *nordvpn) filterServers(regions []string, protocol models.NetworkProtocol, numbers []uint16) (servers []models.NordvpnServer) {
for i, server := range n.servers { numbersStr := make([]string, len(numbers))
if len(region) == 0 { for i := range numbers {
server.Region = "" numbersStr[i] = fmt.Sprintf("%d", numbers[i])
} }
if number == 0 { for _, server := range n.servers {
server.Number = 0 numberStr := fmt.Sprintf("%d", server.Number)
} switch {
case
if protocol == constants.TCP && !server.TCP { protocol == constants.TCP && !server.TCP,
continue protocol == constants.UDP && !server.UDP,
} else if protocol == constants.UDP && !server.UDP { filterByPossibilities(server.Region, regions),
continue filterByPossibilities(numberStr, numbersStr):
} default:
if strings.EqualFold(server.Region, region) && server.Number == number { servers = append(servers, server)
servers = append(servers, n.servers[i])
} }
} }
return servers return servers
@@ -63,9 +61,9 @@ func (n *nordvpn) GetOpenVPNConnection(selection models.ServerSelection) (connec
return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil
} }
servers := n.filterServers(selection.Region, selection.Protocol, selection.Number) servers := n.filterServers(selection.Regions, selection.Protocol, selection.Numbers)
if len(servers) == 0 { if len(servers) == 0 {
return connection, fmt.Errorf("no server found for region %q, protocol %s and number %d", selection.Region, selection.Protocol, selection.Number) return connection, fmt.Errorf("no server found for region %s, protocol %s and numbers %v", commaJoin(selection.Regions), selection.Protocol, selection.Numbers)
} }
connections := make([]models.OpenVPNConnection, len(servers)) connections := make([]models.OpenVPNConnection, len(servers))

View File

@@ -9,7 +9,6 @@ import (
"math/rand" "math/rand"
"net" "net"
"net/http" "net/http"
"strings"
"github.com/qdm12/gluetun/internal/constants" "github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/firewall" "github.com/qdm12/gluetun/internal/firewall"
@@ -57,9 +56,9 @@ func (p *piaV3) GetOpenVPNConnection(selection models.ServerSelection) (connecti
return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil
} }
servers := filterPIAOldServers(p.servers, selection.Region) servers := filterPIAOldServers(p.servers, selection.Regions)
if len(servers) == 0 { if len(servers) == 0 {
return connection, fmt.Errorf("no server found for region %q", selection.Region) return connection, fmt.Errorf("no server found for regions %s", commaJoin(selection.Regions))
} }
var connections []models.OpenVPNConnection var connections []models.OpenVPNConnection
@@ -136,14 +135,13 @@ func (p *piaV3) PortForward(ctx context.Context, client *http.Client,
} }
} }
func filterPIAOldServers(servers []models.PIAOldServer, region string) (filtered []models.PIAOldServer) { func filterPIAOldServers(servers []models.PIAOldServer, regions []string) (filtered []models.PIAOldServer) {
if len(region) == 0 {
return servers
}
for _, server := range servers { for _, server := range servers {
if strings.EqualFold(server.Region, region) { switch {
return []models.PIAOldServer{server} case filterByPossibilities(server.Region, regions):
default:
servers = append(servers, server)
} }
} }
return nil return servers
} }

View File

@@ -66,9 +66,9 @@ func (p *piaV4) GetOpenVPNConnection(selection models.ServerSelection) (connecti
return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil
} }
servers := filterPIAServers(p.servers, selection.Region) servers := filterPIAServers(p.servers, selection.Regions)
if len(servers) == 0 { if len(servers) == 0 {
return connection, fmt.Errorf("no server found for region %q", selection.Region) return connection, fmt.Errorf("no server found for region %s", commaJoin(selection.Regions))
} }
var connections []models.OpenVPNConnection var connections []models.OpenVPNConnection
@@ -246,16 +246,15 @@ func (p *piaV4) PortForward(ctx context.Context, client *http.Client,
} }
} }
func filterPIAServers(servers []models.PIAServer, region string) (filtered []models.PIAServer) { func filterPIAServers(servers []models.PIAServer, regions []string) (filtered []models.PIAServer) {
if len(region) == 0 {
return servers
}
for _, server := range servers { for _, server := range servers {
if strings.EqualFold(server.Region, region) { switch {
return []models.PIAServer{server} case filterByPossibilities(server.Region, regions):
default:
servers = append(servers, server)
} }
} }
return nil return servers
} }
func newPIAv4HTTPClient(serverName string) (client *http.Client, err error) { func newPIAv4HTTPClient(serverName string) (client *http.Client, err error) {

View File

@@ -6,7 +6,6 @@ import (
"math/rand" "math/rand"
"net" "net"
"net/http" "net/http"
"strings"
"github.com/qdm12/gluetun/internal/constants" "github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/firewall" "github.com/qdm12/gluetun/internal/firewall"
@@ -27,21 +26,15 @@ func newPurevpn(servers []models.PurevpnServer, timeNow timeNowFunc) *purevpn {
} }
} }
func (p *purevpn) filterServers(region, country, city string) (servers []models.PurevpnServer) { func (p *purevpn) filterServers(regions, countries, cities []string) (servers []models.PurevpnServer) {
for i, server := range p.servers { for _, server := range p.servers {
if len(region) == 0 { switch {
server.Region = "" case
} filterByPossibilities(server.Region, regions),
if len(country) == 0 { filterByPossibilities(server.Country, countries),
server.Country = "" filterByPossibilities(server.City, cities):
} default:
if len(city) == 0 { servers = append(servers, server)
server.City = ""
}
if strings.EqualFold(server.Region, region) &&
strings.EqualFold(server.Country, country) &&
strings.EqualFold(server.City, city) {
servers = append(servers, p.servers[i])
} }
} }
return servers return servers
@@ -62,9 +55,10 @@ func (p *purevpn) GetOpenVPNConnection(selection models.ServerSelection) (connec
return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil
} }
servers := p.filterServers(selection.Region, selection.Country, selection.City) servers := p.filterServers(selection.Regions, selection.Countries, selection.Cities)
if len(servers) == 0 { if len(servers) == 0 {
return connection, fmt.Errorf("no server found for region %q, country %q and city %q", selection.Region, selection.Country, selection.City) return connection, fmt.Errorf("no server found for regions %s, countries %s and cities %s",
commaJoin(selection.Regions), commaJoin(selection.Countries), commaJoin(selection.Cities))
} }
var connections []models.OpenVPNConnection var connections []models.OpenVPNConnection

View File

@@ -6,7 +6,6 @@ import (
"math/rand" "math/rand"
"net" "net"
"net/http" "net/http"
"strings"
"github.com/qdm12/gluetun/internal/constants" "github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/firewall" "github.com/qdm12/gluetun/internal/firewall"
@@ -27,16 +26,16 @@ func newSurfshark(servers []models.SurfsharkServer, timeNow timeNowFunc) *surfsh
} }
} }
func (s *surfshark) filterServers(region string) (servers []models.SurfsharkServer) { func (s *surfshark) filterServers(regions []string) (servers []models.SurfsharkServer) {
if len(region) == 0 {
return s.servers
}
for _, server := range s.servers { for _, server := range s.servers {
if strings.EqualFold(server.Region, region) { switch {
return []models.SurfsharkServer{server} case
filterByPossibilities(server.Region, regions):
default:
servers = append(servers, server)
} }
} }
return nil return servers
} }
func (s *surfshark) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) { //nolint:dupl func (s *surfshark) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) { //nolint:dupl
@@ -54,9 +53,9 @@ func (s *surfshark) GetOpenVPNConnection(selection models.ServerSelection) (conn
return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil
} }
servers := s.filterServers(selection.Region) servers := s.filterServers(selection.Regions)
if len(servers) == 0 { if len(servers) == 0 {
return connection, fmt.Errorf("no server found for region %q", selection.Region) return connection, fmt.Errorf("no server found for region %s", commaJoin(selection.Regions))
} }
var connections []models.OpenVPNConnection var connections []models.OpenVPNConnection

View File

@@ -3,6 +3,7 @@ package provider
import ( import (
"context" "context"
"math/rand" "math/rand"
"strings"
"time" "time"
"github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/models"
@@ -35,3 +36,19 @@ func tryUntilSuccessful(ctx context.Context, logger logging.Logger, fn func() er
func pickRandomConnection(connections []models.OpenVPNConnection, source rand.Source) models.OpenVPNConnection { func pickRandomConnection(connections []models.OpenVPNConnection, source rand.Source) models.OpenVPNConnection {
return connections[rand.New(source).Intn(len(connections))] //nolint:gosec return connections[rand.New(source).Intn(len(connections))] //nolint:gosec
} }
func filterByPossibilities(value string, possibilities []string) (filtered bool) {
if len(possibilities) == 0 {
return false
}
for _, possibility := range possibilities {
if strings.EqualFold(value, possibility) {
return false
}
}
return true
}
func commaJoin(slice []string) string {
return strings.Join(slice, ",")
}

View File

@@ -6,7 +6,6 @@ import (
"math/rand" "math/rand"
"net" "net"
"net/http" "net/http"
"strings"
"github.com/qdm12/gluetun/internal/constants" "github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/firewall" "github.com/qdm12/gluetun/internal/firewall"
@@ -27,16 +26,16 @@ func newVyprvpn(servers []models.VyprvpnServer, timeNow timeNowFunc) *vyprvpn {
} }
} }
func (v *vyprvpn) filterServers(region string) (servers []models.VyprvpnServer) { func (v *vyprvpn) filterServers(regions []string) (servers []models.VyprvpnServer) {
if len(region) == 0 {
return v.servers
}
for _, server := range v.servers { for _, server := range v.servers {
if strings.EqualFold(server.Region, region) { switch {
return []models.VyprvpnServer{server} case
filterByPossibilities(server.Region, regions):
default:
servers = append(servers, server)
} }
} }
return nil return servers
} }
func (v *vyprvpn) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) { func (v *vyprvpn) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) {
@@ -54,9 +53,9 @@ func (v *vyprvpn) GetOpenVPNConnection(selection models.ServerSelection) (connec
return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil
} }
servers := v.filterServers(selection.Region) servers := v.filterServers(selection.Regions)
if len(servers) == 0 { if len(servers) == 0 {
return connection, fmt.Errorf("no server found for region %q", selection.Region) return connection, fmt.Errorf("no server found for region %s", commaJoin(selection.Regions))
} }
var connections []models.OpenVPNConnection var connections []models.OpenVPNConnection

View File

@@ -27,16 +27,16 @@ func newWindscribe(servers []models.WindscribeServer, timeNow timeNowFunc) *wind
} }
} }
func (w *windscribe) filterServers(region string) (servers []models.WindscribeServer) { func (w *windscribe) filterServers(regions []string) (servers []models.WindscribeServer) {
if len(region) == 0 {
return w.servers
}
for _, server := range w.servers { for _, server := range w.servers {
if strings.EqualFold(server.Region, region) { switch {
return []models.WindscribeServer{server} case
filterByPossibilities(server.Region, regions):
default:
servers = append(servers, server)
} }
} }
return nil return servers
} }
func (w *windscribe) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) { func (w *windscribe) GetOpenVPNConnection(selection models.ServerSelection) (connection models.OpenVPNConnection, err error) {
@@ -56,9 +56,9 @@ func (w *windscribe) GetOpenVPNConnection(selection models.ServerSelection) (con
return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil
} }
servers := w.filterServers(selection.Region) servers := w.filterServers(selection.Regions)
if len(servers) == 0 { if len(servers) == 0 {
return connection, fmt.Errorf("no server found for region %q", selection.Region) return connection, fmt.Errorf("no server found for region %s", commaJoin(selection.Regions))
} }
var connections []models.OpenVPNConnection var connections []models.OpenVPNConnection

View File

@@ -19,7 +19,7 @@ func Test_OpenVPN_JSON(t *testing.T) {
} }
data, err := json.Marshal(in) data, err := json.Marshal(in)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, `{"user":"","verbosity":0,"runAsRoot":true,"cipher":"","auth":"","provider":{"name":"name","serverSelection":{"networkProtocol":"","region":"","group":"","country":"","city":"","isp":"","owned":false,"customPort":0,"number":0,"encryptionPreset":""},"extraConfig":{"encryptionPreset":"","openvpnIPv6":false},"portForwarding":{"enabled":false,"filepath":""}}}`, string(data)) assert.Equal(t, `{"user":"","verbosity":0,"runAsRoot":true,"cipher":"","auth":"","provider":{"name":"name","serverSelection":{"networkProtocol":"","regions":null,"group":"","countries":null,"cities":null,"isps":null,"owned":false,"customPort":0,"numbers":null,"encryptionPreset":""},"extraConfig":{"encryptionPreset":"","openvpnIPv6":false},"portForwarding":{"enabled":false,"filepath":""}}}`, string(data))
var out OpenVPN var out OpenVPN
err = json.Unmarshal(data, &out) err = json.Unmarshal(data, &out)
require.NoError(t, err) require.NoError(t, err)

View File

@@ -34,7 +34,7 @@ func getPIASettings(paramsReader params.Reader, name models.VPNProvider) (settin
} }
settings.ServerSelection.EncryptionPreset = encryptionPreset settings.ServerSelection.EncryptionPreset = encryptionPreset
settings.ExtraConfigOptions.EncryptionPreset = encryptionPreset settings.ExtraConfigOptions.EncryptionPreset = encryptionPreset
settings.ServerSelection.Region, err = paramsReader.GetPIARegion() settings.ServerSelection.Regions, err = paramsReader.GetPIARegions()
if err != nil { if err != nil {
return settings, err return settings, err
} }
@@ -62,15 +62,15 @@ func GetMullvadSettings(paramsReader params.Reader) (settings models.ProviderSet
if err != nil { if err != nil {
return settings, err return settings, err
} }
settings.ServerSelection.Country, err = paramsReader.GetMullvadCountry() settings.ServerSelection.Countries, err = paramsReader.GetMullvadCountries()
if err != nil { if err != nil {
return settings, err return settings, err
} }
settings.ServerSelection.City, err = paramsReader.GetMullvadCity() settings.ServerSelection.Cities, err = paramsReader.GetMullvadCities()
if err != nil { if err != nil {
return settings, err return settings, err
} }
settings.ServerSelection.ISP, err = paramsReader.GetMullvadISP() settings.ServerSelection.ISPs, err = paramsReader.GetMullvadISPs()
if err != nil { if err != nil {
return settings, err return settings, err
} }
@@ -91,6 +91,10 @@ func GetMullvadSettings(paramsReader params.Reader) (settings models.ProviderSet
return settings, fmt.Errorf("port %d is not valid for UDP protocol", settings.ServerSelection.CustomPort) return settings, fmt.Errorf("port %d is not valid for UDP protocol", settings.ServerSelection.CustomPort)
} }
} }
settings.ServerSelection.Owned, err = paramsReader.GetMullvadOwned()
if err != nil {
return settings, err
}
settings.ExtraConfigOptions.OpenVPNIPv6, err = paramsReader.GetOpenVPNIPv6() settings.ExtraConfigOptions.OpenVPNIPv6, err = paramsReader.GetOpenVPNIPv6()
if err != nil { if err != nil {
return settings, err return settings, err
@@ -109,7 +113,7 @@ func GetWindscribeSettings(paramsReader params.Reader) (settings models.Provider
if err != nil { if err != nil {
return settings, err return settings, err
} }
settings.ServerSelection.Region, err = paramsReader.GetWindscribeRegion() settings.ServerSelection.Regions, err = paramsReader.GetWindscribeRegions()
if err != nil { if err != nil {
return settings, err return settings, err
} }
@@ -131,7 +135,7 @@ func GetSurfsharkSettings(paramsReader params.Reader) (settings models.ProviderS
if err != nil { if err != nil {
return settings, err return settings, err
} }
settings.ServerSelection.Region, err = paramsReader.GetSurfsharkRegion() settings.ServerSelection.Regions, err = paramsReader.GetSurfsharkRegions()
if err != nil { if err != nil {
return settings, err return settings, err
} }
@@ -157,7 +161,7 @@ func GetCyberghostSettings(paramsReader params.Reader) (settings models.Provider
if err != nil { if err != nil {
return settings, err return settings, err
} }
settings.ServerSelection.Region, err = paramsReader.GetCyberghostRegion() settings.ServerSelection.Regions, err = paramsReader.GetCyberghostRegions()
if err != nil { if err != nil {
return settings, err return settings, err
} }
@@ -175,7 +179,7 @@ func GetVyprvpnSettings(paramsReader params.Reader) (settings models.ProviderSet
if err != nil { if err != nil {
return settings, err return settings, err
} }
settings.ServerSelection.Region, err = paramsReader.GetVyprvpnRegion() settings.ServerSelection.Regions, err = paramsReader.GetVyprvpnRegions()
if err != nil { if err != nil {
return settings, err return settings, err
} }
@@ -193,11 +197,11 @@ func GetNordvpnSettings(paramsReader params.Reader) (settings models.ProviderSet
if err != nil { if err != nil {
return settings, err return settings, err
} }
settings.ServerSelection.Region, err = paramsReader.GetNordvpnRegion() settings.ServerSelection.Regions, err = paramsReader.GetNordvpnRegions()
if err != nil { if err != nil {
return settings, err return settings, err
} }
settings.ServerSelection.Number, err = paramsReader.GetNordvpnNumber() settings.ServerSelection.Numbers, err = paramsReader.GetNordvpnNumbers()
if err != nil { if err != nil {
return settings, err return settings, err
} }
@@ -215,15 +219,15 @@ func GetPurevpnSettings(paramsReader params.Reader) (settings models.ProviderSet
if err != nil { if err != nil {
return settings, err return settings, err
} }
settings.ServerSelection.Region, err = paramsReader.GetPurevpnRegion() settings.ServerSelection.Regions, err = paramsReader.GetPurevpnRegions()
if err != nil { if err != nil {
return settings, err return settings, err
} }
settings.ServerSelection.Country, err = paramsReader.GetPurevpnCountry() settings.ServerSelection.Countries, err = paramsReader.GetPurevpnCountries()
if err != nil { if err != nil {
return settings, err return settings, err
} }
settings.ServerSelection.City, err = paramsReader.GetPurevpnCity() settings.ServerSelection.Cities, err = paramsReader.GetPurevpnCities()
if err != nil { if err != nil {
return settings, err return settings, err
} }