You've already forked ddns-updater
FEAT: Refactor allowing multiple DNS Providers
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
104
main.go
104
main.go
@@ -8,8 +8,9 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/cloudflare/cloudflare-go"
|
||||
"github.com/mkelcik/cloudflare-ddns-update/internal"
|
||||
"github.com/mkelcik/cloudflare-ddns-update/internal/dns_providers"
|
||||
"github.com/mkelcik/cloudflare-ddns-update/internal/dns_resolver"
|
||||
"github.com/mkelcik/cloudflare-ddns-update/notifications"
|
||||
"github.com/mkelcik/cloudflare-ddns-update/public_resolvers"
|
||||
)
|
||||
@@ -34,6 +35,17 @@ func getResolver(resolverName string) (PublicIpResolver, string) {
|
||||
}
|
||||
}
|
||||
|
||||
func getProvider(ctx context.Context, config internal.Config) (dns_providers.DNSProvider, string) {
|
||||
switch config.DNSProviderTag {
|
||||
case dns_providers.DirectadminTag:
|
||||
return dns_providers.NewDirectAdminProvider(ctx, config), dns_providers.DirectadminTag
|
||||
case dns_providers.CloudflareTag:
|
||||
fallthrough
|
||||
default:
|
||||
return dns_providers.NewCloudflareProvider(ctx, config), dns_providers.CloudflareTag
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer stop()
|
||||
@@ -43,68 +55,50 @@ func main() {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
api, err := cloudflare.NewWithAPIToken(config.ApiToken)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Fetch user details on the account
|
||||
zoneID, err := api.ZoneIDByName(config.CloudflareZone)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
notifiers := notifications.GetNotifiers(config.Notifiers)
|
||||
|
||||
// public ip resolver
|
||||
publicIpResolver, resolverTag := getResolver(config.PublicIpResolverTag)
|
||||
dnsProvider, providerTag := getProvider(ctx, config)
|
||||
log.Printf("Using DNS Provider %s", providerTag)
|
||||
|
||||
checkFunc := func() {
|
||||
currentPublicIP, err := publicIpResolver.ResolvePublicIp(ctx)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Printf("Current public ip `%s` (resolver: %s)", currentPublicIP, resolverTag)
|
||||
|
||||
dns, err := allDNSRecords(ctx, api, cloudflare.ZoneIdentifier(zoneID))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, dnsRecord := range dns {
|
||||
if internal.Contains(config.DnsRecordsToCheck, dnsRecord.Name) {
|
||||
log.Printf("Checking record `%s` with current value `%s` ...", dnsRecord.Name, dnsRecord.Content)
|
||||
if currentPublicIP.String() == dnsRecord.Content {
|
||||
log.Println("OK")
|
||||
continue // no update needed
|
||||
}
|
||||
for _, dnsRecord := range config.DnsRecordsToCheck {
|
||||
current_dns_record := dns_resolver.ResolveHostname(dnsRecord, "1.1.1.1")
|
||||
|
||||
update := cloudflare.UpdateDNSRecordParams{
|
||||
ID: dnsRecord.ID,
|
||||
Content: currentPublicIP.String(),
|
||||
}
|
||||
|
||||
if config.OnChangeComment != "" {
|
||||
update.Comment = &config.OnChangeComment
|
||||
}
|
||||
|
||||
if _, err := api.UpdateDNSRecord(ctx, cloudflare.ZoneIdentifier(zoneID), update); err != nil {
|
||||
log.Printf("error updating dns record: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := notifiers.NotifyWithLog(ctx, notifications.Notification{
|
||||
OldIp: net.ParseIP(dnsRecord.Content),
|
||||
NewIp: currentPublicIP,
|
||||
CheckedAt: time.Now(),
|
||||
ResolverTag: resolverTag,
|
||||
Domain: dnsRecord.Name,
|
||||
WebhookToken: config.WebhookToken,
|
||||
}); err != nil {
|
||||
log.Printf("errors in notifications: %s", err)
|
||||
}
|
||||
log.Printf("Updated to `%s`", currentPublicIP)
|
||||
log.Printf("Checking record `%s` with current value `%s` ...", dnsRecord, current_dns_record.String())
|
||||
if currentPublicIP.String() == current_dns_record.String() {
|
||||
log.Println("OK")
|
||||
continue // no update needed
|
||||
}
|
||||
|
||||
if err := dnsProvider.UpdateRecord(dnsRecord, currentPublicIP.String(), current_dns_record.String()); err != nil {
|
||||
log.Printf("error updating dns record: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := notifiers.NotifyWithLog(ctx, notifications.Notification{
|
||||
OldIp: net.ParseIP(string(current_dns_record)),
|
||||
NewIp: currentPublicIP,
|
||||
CheckedAt: time.Now(),
|
||||
ResolverTag: resolverTag,
|
||||
Domain: dnsRecord,
|
||||
WebhookToken: config.WebhookToken,
|
||||
}); err != nil {
|
||||
log.Printf("errors in notifications: %s", err)
|
||||
}
|
||||
log.Printf("Updated to `%s`", currentPublicIP)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,23 +118,3 @@ func main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func allDNSRecords(ctx context.Context, api *cloudflare.API, rc *cloudflare.ResourceContainer) ([]cloudflare.DNSRecord, error) {
|
||||
out := make([]cloudflare.DNSRecord, 0, 100)
|
||||
params := cloudflare.ListDNSRecordsParams{
|
||||
ResultInfo: cloudflare.ResultInfo{Page: 1},
|
||||
}
|
||||
for {
|
||||
page, res, err := api.ListDNSRecords(ctx, rc, params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, page...)
|
||||
|
||||
if res.Page >= res.TotalPages {
|
||||
break
|
||||
}
|
||||
params.Page++
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user