// Package ipvanish contains code to obtain the server information // for the Surshark provider. package ipvanish import ( "context" "fmt" "strings" "github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/provider/common" "github.com/qdm12/gluetun/internal/updater/openvpn" "golang.org/x/text/cases" "golang.org/x/text/language" ) func (u *Updater) GetServers(ctx context.Context, minServers int) ( servers []models.Server, err error) { const url = "https://www.ipvanish.com/software/configs/configs.zip" contents, err := u.unzipper.FetchAndExtract(ctx, url) if err != nil { return nil, err } else if len(contents) < minServers { return nil, fmt.Errorf("%w: %d and expected at least %d", common.ErrNotEnoughServers, len(contents), minServers) } hts := make(hostToServer) titleCaser := cases.Title(language.English) for fileName, content := range contents { if !strings.HasSuffix(fileName, ".ovpn") { continue // not an OpenVPN file } tcp, udp, err := openvpn.ExtractProto(content) if err != nil { // treat error as warning and go to next file u.warner.Warn(err.Error() + " in " + fileName) continue } hostname, warning, err := openvpn.ExtractHost(content) if warning != "" { u.warner.Warn(warning) } if err != nil { // treat error as warning and go to next file u.warner.Warn(err.Error() + " in " + fileName) continue } country, city, err := parseFilename(fileName, hostname, titleCaser) if err != nil { // treat error as warning and go to next file u.warner.Warn(err.Error() + " in " + fileName) continue } hts.add(hostname, country, city, tcp, udp) } if len(hts) < minServers { return nil, fmt.Errorf("%w: %d and expected at least %d", common.ErrNotEnoughServers, len(hts), minServers) } hosts := hts.toHostsSlice() hostToIPs, warnings, err := resolveHosts(ctx, u.presolver, hosts, minServers) for _, warning := range warnings { u.warner.Warn(warning) } if err != nil { return nil, err } hts.adaptWithIPs(hostToIPs) servers = hts.toServersSlice() if len(servers) < minServers { return nil, fmt.Errorf("%w: %d and expected at least %d", common.ErrNotEnoughServers, len(servers), minServers) } sortServers(servers) return servers, nil }