package updater import ( "context" "fmt" "sort" "github.com/qdm12/gluetun/internal/constants/vpn" "github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/provider/common" "github.com/qdm12/gluetun/internal/updater/openvpn" ) func (u *Updater) FetchServers(ctx context.Context, minServers int) ( servers []models.Server, err error) { hostToData, err := fetchServers(ctx, u.client) if err != nil { return nil, fmt.Errorf("fetching and parsing website: %w", err) } openvpnURLs := make([]string, 0, len(hostToData)) for _, data := range hostToData { openvpnURLs = append(openvpnURLs, data.ovpnURL) } if len(openvpnURLs) < minServers { return nil, fmt.Errorf("%w: %d and expected at least %d", common.ErrNotEnoughServers, len(openvpnURLs), minServers) } const failEarly = false // some URLs from the website are not valid hostToURL, errors := openvpn.FetchMultiFiles(ctx, u.client, openvpnURLs, failEarly) for _, err := range errors { u.warner.Warn(fmt.Sprintf("fetching OpenVPN files: %s", err)) } if len(hostToURL) < minServers { return nil, fmt.Errorf("%w: %d and expected at least %d", common.ErrNotEnoughServers, len(hostToURL), minServers) } hosts := make([]string, 0, len(hostToURL)) for host := range hostToURL { hosts = append(hosts, host) } resolveSettings := parallelResolverSettings(hosts) hostToIPs, warnings, err := u.parallelResolver.Resolve(ctx, resolveSettings) for _, warning := range warnings { u.warner.Warn(warning) } if err != nil { return nil, fmt.Errorf("resolving hosts: %w", err) } if len(hostToIPs) < minServers { return nil, fmt.Errorf("%w: %d and expected at least %d", common.ErrNotEnoughServers, len(hosts), minServers) } servers = make([]models.Server, 0, len(hostToIPs)) for host, IPs := range hostToIPs { serverData := hostToData[host] server := models.Server{ VPN: vpn.OpenVPN, Region: serverData.region, Country: serverData.country, City: serverData.city, Hostname: host, UDP: true, TCP: true, IPs: IPs, } servers = append(servers, server) } sort.Sort(models.SortableServers(servers)) return servers, nil }