2020-12-29 18:24:03 +00:00
|
|
|
package cli
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
2021-05-30 16:14:08 +00:00
|
|
|
"errors"
|
2020-12-29 18:24:03 +00:00
|
|
|
"flag"
|
|
|
|
|
"fmt"
|
|
|
|
|
"net/http"
|
2022-01-06 06:40:23 -05:00
|
|
|
"strings"
|
2020-12-29 18:24:03 +00:00
|
|
|
"time"
|
|
|
|
|
|
2022-01-06 06:40:23 -05:00
|
|
|
"github.com/qdm12/gluetun/internal/configuration/settings"
|
2020-12-29 18:24:03 +00:00
|
|
|
"github.com/qdm12/gluetun/internal/constants"
|
2022-04-16 19:30:26 +00:00
|
|
|
"github.com/qdm12/gluetun/internal/constants/providers"
|
2022-06-10 00:47:56 +00:00
|
|
|
"github.com/qdm12/gluetun/internal/provider"
|
2020-12-29 18:24:03 +00:00
|
|
|
"github.com/qdm12/gluetun/internal/storage"
|
|
|
|
|
"github.com/qdm12/gluetun/internal/updater"
|
2022-06-11 17:41:57 +00:00
|
|
|
"github.com/qdm12/gluetun/internal/updater/resolver"
|
2022-06-10 00:47:56 +00:00
|
|
|
"github.com/qdm12/gluetun/internal/updater/unzip"
|
2020-12-29 18:24:03 +00:00
|
|
|
)
|
|
|
|
|
|
2021-05-30 16:14:08 +00:00
|
|
|
var (
|
2022-02-20 02:58:16 +00:00
|
|
|
ErrModeUnspecified = errors.New("at least one of -enduser or -maintainer must be specified")
|
|
|
|
|
ErrNoProviderSpecified = errors.New("no provider was specified")
|
2021-05-30 16:14:08 +00:00
|
|
|
)
|
|
|
|
|
|
2021-09-23 16:58:21 +00:00
|
|
|
type UpdaterLogger interface {
|
|
|
|
|
Info(s string)
|
|
|
|
|
Warn(s string)
|
|
|
|
|
Error(s string)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *CLI) Update(ctx context.Context, args []string, logger UpdaterLogger) error {
|
2022-05-28 20:58:50 +00:00
|
|
|
options := settings.Updater{}
|
2021-07-23 02:47:04 +00:00
|
|
|
var endUserMode, maintainerMode, updateAll bool
|
2022-06-11 20:11:20 +00:00
|
|
|
var csvProviders string
|
2020-12-29 18:24:03 +00:00
|
|
|
flagSet := flag.NewFlagSet("update", flag.ExitOnError)
|
2021-07-20 03:01:26 +00:00
|
|
|
flagSet.BoolVar(&endUserMode, "enduser", false, "Write results to /gluetun/servers.json (for end users)")
|
|
|
|
|
flagSet.BoolVar(&maintainerMode, "maintainer", false,
|
2021-09-06 13:41:45 +00:00
|
|
|
"Write results to ./internal/storage/servers.json to modify the program (for maintainers)")
|
2022-06-11 20:11:20 +00:00
|
|
|
flagSet.StringVar(&options.DNSAddress, "dns", "8.8.8.8", "DNS resolver address to use")
|
2021-07-23 02:47:04 +00:00
|
|
|
flagSet.BoolVar(&updateAll, "all", false, "Update servers for all VPN providers")
|
2022-01-06 06:40:23 -05:00
|
|
|
flagSet.StringVar(&csvProviders, "providers", "", "CSV string of VPN providers to update server data for")
|
2020-12-29 18:24:03 +00:00
|
|
|
if err := flagSet.Parse(args); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2022-01-06 06:40:23 -05:00
|
|
|
|
2021-07-20 03:01:26 +00:00
|
|
|
if !endUserMode && !maintainerMode {
|
|
|
|
|
return ErrModeUnspecified
|
2020-12-29 18:24:03 +00:00
|
|
|
}
|
2021-01-30 17:29:27 +00:00
|
|
|
|
2021-07-23 02:47:04 +00:00
|
|
|
if updateAll {
|
2022-05-27 00:59:47 +00:00
|
|
|
options.Providers = providers.All()
|
2022-01-06 06:40:23 -05:00
|
|
|
} else {
|
|
|
|
|
if csvProviders == "" {
|
|
|
|
|
return ErrNoProviderSpecified
|
|
|
|
|
}
|
|
|
|
|
options.Providers = strings.Split(csvProviders, ",")
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-26 22:40:57 +00:00
|
|
|
options.SetDefaults(options.Providers[0])
|
2022-01-07 22:29:30 +00:00
|
|
|
|
2022-01-06 06:40:23 -05:00
|
|
|
err := options.Validate()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("options validation failed: %w", err)
|
2021-07-23 02:47:04 +00:00
|
|
|
}
|
|
|
|
|
|
2021-08-27 19:10:03 +00:00
|
|
|
storage, err := storage.New(logger, constants.ServersData)
|
2020-12-29 18:24:03 +00:00
|
|
|
if err != nil {
|
2022-02-20 02:58:16 +00:00
|
|
|
return fmt.Errorf("cannot create servers storage: %w", err)
|
2020-12-29 18:24:03 +00:00
|
|
|
}
|
2021-08-27 19:10:03 +00:00
|
|
|
|
2022-06-11 17:41:57 +00:00
|
|
|
const clientTimeout = 10 * time.Second
|
|
|
|
|
httpClient := &http.Client{Timeout: clientTimeout}
|
2022-06-10 00:47:56 +00:00
|
|
|
unzipper := unzip.New(httpClient)
|
2022-06-11 20:11:20 +00:00
|
|
|
parallelResolver := resolver.NewParallelResolver(options.DNSAddress)
|
2022-06-10 00:47:56 +00:00
|
|
|
|
2022-06-11 17:41:57 +00:00
|
|
|
providers := provider.NewProviders(storage, time.Now, logger, httpClient, unzipper, parallelResolver)
|
2022-06-10 00:47:56 +00:00
|
|
|
|
|
|
|
|
updater := updater.New(httpClient, storage, providers, logger)
|
2022-06-09 23:47:12 +00:00
|
|
|
err = updater.UpdateServers(ctx, options.Providers)
|
2020-12-29 18:24:03 +00:00
|
|
|
if err != nil {
|
2022-02-20 02:58:16 +00:00
|
|
|
return fmt.Errorf("cannot update server information: %w", err)
|
2020-12-29 18:24:03 +00:00
|
|
|
}
|
2021-07-20 03:01:26 +00:00
|
|
|
|
|
|
|
|
if maintainerMode {
|
2022-06-05 14:58:46 +00:00
|
|
|
err := storage.FlushToFile(c.repoServersPath)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("cannot write servers data to embedded JSON file: %w", err)
|
2021-07-20 03:01:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-29 18:24:03 +00:00
|
|
|
return nil
|
|
|
|
|
}
|