Files
gluetun/internal/publicip/update.go
Quentin McGaw a61302f135 feat(publicip): resilient public ip fetcher (#2518)
- `PUBLICIP_API` accepts a comma separated list of ip data sources, where the first one is the base default one, and sources after it are backup sources used if we are rate limited.
- `PUBLICIP_API` defaults to `ipinfo,ifconfigco,ip2location,cloudflare` such that it now has `ifconfigco,ip2location,cloudflare` as backup ip data sources.
- `PUBLICIP_API_TOKEN` accepts a comma separated list of ip data source tokens, each corresponding by position to the APIs listed in `PUBLICIP_API`.
- logs ip data source when logging public ip information
- assume a rate limiting error is for 30 days (no persistence)
- ready for future live settings updates
  - consider an ip data source no longer banned if the token changes
  - keeps track of ban times when updating the list of fetchers
2024-10-19 15:21:14 +02:00

55 lines
1.3 KiB
Go

package publicip
import (
"fmt"
"os"
"reflect"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/publicip/api"
)
func (l *Loop) update(partialUpdate settings.PublicIP) (err error) {
l.settingsMutex.Lock()
defer l.settingsMutex.Unlock()
updatedSettings, err := l.settings.UpdateWith(partialUpdate)
if err != nil {
return err
}
if *l.settings.IPFilepath != *updatedSettings.IPFilepath {
switch {
case *l.settings.IPFilepath == "":
err = persistPublicIP(*updatedSettings.IPFilepath,
l.ipData.IP.String(), l.puid, l.pgid)
if err != nil {
return fmt.Errorf("persisting ip data: %w", err)
}
case *updatedSettings.IPFilepath == "":
err = os.Remove(*l.settings.IPFilepath)
if err != nil {
return fmt.Errorf("removing ip data file path: %w", err)
}
default:
err = os.Rename(*l.settings.IPFilepath, *updatedSettings.IPFilepath)
if err != nil {
return fmt.Errorf("renaming ip data file path: %w", err)
}
}
}
if !reflect.DeepEqual(l.settings.APIs, updatedSettings.APIs) {
newFetchers, err := api.New(makeNameTokenPairs(updatedSettings.APIs), l.httpClient)
if err != nil {
return fmt.Errorf("creating fetchers: %w", err)
}
l.fetcher.UpdateFetchers(newFetchers)
}
l.settings = updatedSettings
return nil
}