feat(publicip/ipinfo): add PUBLICIP_API_TOKEN variable
This commit is contained in:
@@ -190,6 +190,7 @@ ENV VPN_SERVICE_PROVIDER=pia \
|
||||
# Public IP
|
||||
PUBLICIP_FILE="/tmp/gluetun/ip" \
|
||||
PUBLICIP_PERIOD=12h \
|
||||
PUBLICIP_API_TOKEN= \
|
||||
# Pprof
|
||||
PPROF_ENABLED=no \
|
||||
PPROF_BLOCK_PROFILE_RATE=0 \
|
||||
|
||||
@@ -396,7 +396,7 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
|
||||
go unboundLooper.RunRestartTicker(dnsTickerCtx, dnsTickerDone)
|
||||
controlGroupHandler.Add(dnsTickerHandler)
|
||||
|
||||
ipFetcher := ipinfo.New(httpClient)
|
||||
ipFetcher := ipinfo.New(httpClient, *allSettings.PublicIP.APIToken)
|
||||
publicIPLooper := publicip.NewLoop(ipFetcher,
|
||||
logger.New(log.SetComponent("ip getter")),
|
||||
allSettings.PublicIP, puid, pgid)
|
||||
|
||||
@@ -35,7 +35,7 @@ type UpdaterLogger interface {
|
||||
func (c *CLI) Update(ctx context.Context, args []string, logger UpdaterLogger) error {
|
||||
options := settings.Updater{}
|
||||
var endUserMode, maintainerMode, updateAll bool
|
||||
var csvProviders string
|
||||
var csvProviders, ipToken string
|
||||
flagSet := flag.NewFlagSet("update", flag.ExitOnError)
|
||||
flagSet.BoolVar(&endUserMode, "enduser", false, "Write results to /gluetun/servers.json (for end users)")
|
||||
flagSet.BoolVar(&maintainerMode, "maintainer", false,
|
||||
@@ -46,6 +46,7 @@ func (c *CLI) Update(ctx context.Context, args []string, logger UpdaterLogger) e
|
||||
"Minimum ratio of servers to find for the update to succeed")
|
||||
flagSet.BoolVar(&updateAll, "all", false, "Update servers for all VPN providers")
|
||||
flagSet.StringVar(&csvProviders, "providers", "", "CSV string of VPN providers to update server data for")
|
||||
flagSet.StringVar(&ipToken, "ip-token", "", "IP data service token (e.g. ipinfo.io) to use")
|
||||
if err := flagSet.Parse(args); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -79,7 +80,7 @@ func (c *CLI) Update(ctx context.Context, args []string, logger UpdaterLogger) e
|
||||
httpClient := &http.Client{Timeout: clientTimeout}
|
||||
unzipper := unzip.New(httpClient)
|
||||
parallelResolver := resolver.NewParallelResolver(options.DNSAddress)
|
||||
ipFetcher := ipinfo.New(httpClient)
|
||||
ipFetcher := ipinfo.New(httpClient, ipToken)
|
||||
openvpnFileExtractor := extract.New()
|
||||
|
||||
providers := provider.NewProviders(storage, time.Now, logger, httpClient,
|
||||
|
||||
@@ -21,6 +21,11 @@ type PublicIP struct {
|
||||
// to write to a file. It cannot be nil for the
|
||||
// internal state
|
||||
IPFilepath *string
|
||||
// APIToken is the token to use for the IP data service
|
||||
// such as ipinfo.io. It can be the empty string to
|
||||
// indicate not to use a token. It cannot be nil for the
|
||||
// internal state.
|
||||
APIToken *string
|
||||
}
|
||||
|
||||
// UpdateWith deep copies the receiving settings, overrides the copy with
|
||||
@@ -58,23 +63,27 @@ func (p *PublicIP) copy() (copied PublicIP) {
|
||||
return PublicIP{
|
||||
Period: gosettings.CopyPointer(p.Period),
|
||||
IPFilepath: gosettings.CopyPointer(p.IPFilepath),
|
||||
APIToken: gosettings.CopyPointer(p.APIToken),
|
||||
}
|
||||
}
|
||||
|
||||
func (p *PublicIP) mergeWith(other PublicIP) {
|
||||
p.Period = gosettings.MergeWithPointer(p.Period, other.Period)
|
||||
p.IPFilepath = gosettings.MergeWithPointer(p.IPFilepath, other.IPFilepath)
|
||||
p.APIToken = gosettings.MergeWithPointer(p.APIToken, other.APIToken)
|
||||
}
|
||||
|
||||
func (p *PublicIP) overrideWith(other PublicIP) {
|
||||
p.Period = gosettings.OverrideWithPointer(p.Period, other.Period)
|
||||
p.IPFilepath = gosettings.OverrideWithPointer(p.IPFilepath, other.IPFilepath)
|
||||
p.APIToken = gosettings.OverrideWithPointer(p.APIToken, other.APIToken)
|
||||
}
|
||||
|
||||
func (p *PublicIP) setDefaults() {
|
||||
const defaultPeriod = 12 * time.Hour
|
||||
p.Period = gosettings.DefaultPointer(p.Period, defaultPeriod)
|
||||
p.IPFilepath = gosettings.DefaultPointer(p.IPFilepath, "/tmp/gluetun/ip")
|
||||
p.APIToken = gosettings.DefaultPointer(p.APIToken, "")
|
||||
}
|
||||
|
||||
func (p PublicIP) String() string {
|
||||
@@ -99,5 +108,9 @@ func (p PublicIP) toLinesNode() (node *gotree.Node) {
|
||||
node.Appendf("IP file path: %s", *p.IPFilepath)
|
||||
}
|
||||
|
||||
if *p.APIToken != "" {
|
||||
node.Appendf("API token: %s", gosettings.ObfuscateKey(*p.APIToken))
|
||||
}
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
@@ -14,5 +14,7 @@ func (s *Source) readPublicIP() (publicIP settings.PublicIP, err error) {
|
||||
publicIP.IPFilepath = s.env.Get("PUBLICIP_FILE",
|
||||
env.ForceLowercase(false), env.RetroKeys("IP_STATUS_FILE"))
|
||||
|
||||
publicIP.APIToken = s.env.Get("PUBLICIP_API_TOKEN")
|
||||
|
||||
return publicIP, nil
|
||||
}
|
||||
|
||||
@@ -14,15 +14,18 @@ import (
|
||||
|
||||
type Fetch struct {
|
||||
client *http.Client
|
||||
token string
|
||||
}
|
||||
|
||||
func New(client *http.Client) *Fetch {
|
||||
func New(client *http.Client, token string) *Fetch {
|
||||
return &Fetch{
|
||||
client: client,
|
||||
token: token,
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
ErrTokenNotValid = errors.New("token is not valid")
|
||||
ErrTooManyRequests = errors.New("too many requests sent for this month")
|
||||
ErrBadHTTPStatus = errors.New("bad HTTP status received")
|
||||
)
|
||||
@@ -44,6 +47,7 @@ func (f *Fetch) FetchInfo(ctx context.Context, ip netip.Addr) (
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
request.Header.Set("Authorization", "Bearer "+f.token)
|
||||
|
||||
response, err := f.client.Do(request)
|
||||
if err != nil {
|
||||
@@ -51,6 +55,10 @@ func (f *Fetch) FetchInfo(ctx context.Context, ip netip.Addr) (
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
if f.token != "" && response.StatusCode == http.StatusUnauthorized {
|
||||
return result, fmt.Errorf("%w: %s", ErrTokenNotValid, response.Status)
|
||||
}
|
||||
|
||||
switch response.StatusCode {
|
||||
case http.StatusOK:
|
||||
case http.StatusTooManyRequests, http.StatusForbidden:
|
||||
|
||||
Reference in New Issue
Block a user