package settings import ( "fmt" "github.com/qdm12/gluetun/internal/constants/providers" "github.com/qdm12/gluetun/internal/constants/vpn" "github.com/qdm12/gosettings" "github.com/qdm12/gosettings/validate" "github.com/qdm12/gotree" ) // Provider contains settings specific to a VPN provider. type Provider struct { // Name is the VPN service provider name. // It cannot be nil in the internal state. Name *string `json:"name"` // ServerSelection is the settings to // select the VPN server. ServerSelection ServerSelection `json:"server_selection"` // PortForwarding is the settings about port forwarding. PortForwarding PortForwarding `json:"port_forwarding"` } // TODO v4 remove pointer for receiver (because of Surfshark). func (p *Provider) validate(vpnType string, storage Storage) (err error) { // Validate Name var validNames []string if vpnType == vpn.OpenVPN { validNames = providers.AllWithCustom() validNames = append(validNames, "pia") // Retro-compatibility } else { // Wireguard validNames = []string{ providers.Airvpn, providers.Custom, providers.Ivpn, providers.Mullvad, providers.Nordvpn, providers.Surfshark, providers.Windscribe, } } if err = validate.IsOneOf(*p.Name, validNames...); err != nil { return fmt.Errorf("%w for Wireguard: %w", ErrVPNProviderNameNotValid, err) } err = p.ServerSelection.validate(*p.Name, storage) if err != nil { return fmt.Errorf("server selection: %w", err) } err = p.PortForwarding.Validate(*p.Name) if err != nil { return fmt.Errorf("port forwarding: %w", err) } return nil } func (p *Provider) copy() (copied Provider) { return Provider{ Name: gosettings.CopyPointer(p.Name), ServerSelection: p.ServerSelection.copy(), PortForwarding: p.PortForwarding.Copy(), } } func (p *Provider) mergeWith(other Provider) { p.Name = gosettings.MergeWithPointer(p.Name, other.Name) p.ServerSelection.mergeWith(other.ServerSelection) p.PortForwarding.mergeWith(other.PortForwarding) } func (p *Provider) overrideWith(other Provider) { p.Name = gosettings.OverrideWithPointer(p.Name, other.Name) p.ServerSelection.overrideWith(other.ServerSelection) p.PortForwarding.OverrideWith(other.PortForwarding) } func (p *Provider) setDefaults() { p.Name = gosettings.DefaultPointer(p.Name, providers.PrivateInternetAccess) p.ServerSelection.setDefaults(*p.Name) p.PortForwarding.setDefaults() } func (p Provider) String() string { return p.toLinesNode().String() } func (p Provider) toLinesNode() (node *gotree.Node) { node = gotree.New("VPN provider settings:") node.Appendf("Name: %s", *p.Name) node.AppendNode(p.ServerSelection.toLinesNode()) node.AppendNode(p.PortForwarding.toLinesNode()) return node }