package sync import ( "go.uber.org/zap" "github.com/bakito/adguardhome-sync/internal/client" "github.com/bakito/adguardhome-sync/internal/client/model" "github.com/bakito/adguardhome-sync/internal/utils" ) var ( actionProfileInfo = func(ac *actionContext) error { if pro, err := ac.client.ProfileInfo(); err != nil { return err } else if merged := pro.ShouldSyncFor(ac.origin.profileInfo, ac.cfg.Features.Theme); merged != nil { return ac.client.SetProfileInfo(merged) } return nil } actionProtection = func(ac *actionContext) error { if ac.origin.status.ProtectionEnabled != ac.replicaStatus.ProtectionEnabled { return ac.client.ToggleProtection(ac.origin.status.ProtectionEnabled) } return nil } actionParental = func(ac *actionContext) error { if rp, err := ac.client.Parental(); err != nil { return err } else if ac.origin.parental != rp { return ac.client.ToggleParental(ac.origin.parental) } return nil } actionSafeSearchConfig = func(ac *actionContext) error { if ssc, err := ac.client.SafeSearchConfig(); err != nil { return err } else if !ac.origin.safeSearch.Equals(ssc) { return ac.client.SetSafeSearchConfig(ac.origin.safeSearch) } return nil } actionSafeBrowsing = func(ac *actionContext) error { if rs, err := ac.client.SafeBrowsing(); err != nil { return err } else if ac.origin.safeBrowsing != rs { if err = ac.client.ToggleSafeBrowsing(ac.origin.safeBrowsing); err != nil { return err } } return nil } actionQueryLogConfig = func(ac *actionContext) error { qlc, err := ac.client.QueryLogConfig() if err != nil { return err } if !ac.origin.queryLogConfig.Equals(qlc) { return ac.client.SetQueryLogConfig(ac.origin.queryLogConfig) } return nil } actionStatsConfig = func(ac *actionContext) error { sc, err := ac.client.StatsConfig() if err != nil { return err } if !sc.Equals(ac.origin.statsConfig) { return ac.client.SetStatsConfig(ac.origin.statsConfig) } return nil } actionDNSRewrites = func(ac *actionContext) error { replicaRewrites, err := ac.client.RewriteList() if err != nil { return err } a, r, d := replicaRewrites.Merge(ac.origin.rewrites) if err = ac.client.DeleteRewriteEntries(r...); err != nil { return err } if err = ac.client.AddRewriteEntries(a...); err != nil { return err } for _, dupl := range d { ac.rl.With("domain", dupl.Domain, "answer", dupl.Answer).Warn("Skipping duplicated rewrite from source") } return nil } actionFilters = func(ac *actionContext) error { rf, err := ac.client.Filtering() if err != nil { return err } if err = syncFilterType(ac.rl, ac.origin.filters.Filters, rf.Filters, false, ac.client, ac.cfg.ContinueOnError); err != nil { return err } if err = syncFilterType(ac.rl, ac.origin.filters.WhitelistFilters, rf.WhitelistFilters, true, ac.client, ac.cfg.ContinueOnError); err != nil { return err } if utils.PtrToString(ac.origin.filters.UserRules) != utils.PtrToString(rf.UserRules) { return ac.client.SetCustomRules(ac.origin.filters.UserRules) } if !utils.PtrEquals(ac.origin.filters.Enabled, rf.Enabled) || !utils.PtrEquals(ac.origin.filters.Interval, rf.Interval) { return ac.client.ToggleFiltering(*ac.origin.filters.Enabled, *ac.origin.filters.Interval) } return nil } actionBlockedServicesSchedule = func(ac *actionContext) error { rbss, err := ac.client.BlockedServicesSchedule() if err != nil { return err } if !ac.origin.blockedServicesSchedule.Equals(rbss) { return ac.client.SetBlockedServicesSchedule(ac.origin.blockedServicesSchedule) } return nil } actionClientSettings = func(ac *actionContext) error { rc, err := ac.client.Clients() if err != nil { return err } a, u, r := rc.Merge(ac.origin.clients) for _, client := range r { if err := ac.client.DeleteClient(client); err != nil { ac.rl.With("client-name", client.Name, "error", err).Error("error deleting client setting") if !ac.cfg.ContinueOnError { return err } } } for _, client := range a { if err := ac.client.AddClient(client); err != nil { ac.rl.With("client-name", client.Name, "error", err).Error("error adding client setting") if !ac.cfg.ContinueOnError { return err } } } for _, client := range u { if err := ac.client.UpdateClient(client); err != nil { ac.rl.With("client-name", client.Name, "error", err).Error("error updating client setting") if !ac.cfg.ContinueOnError { return err } } } return nil } actionDNSAccessLists = func(ac *actionContext) error { al, err := ac.client.AccessList() if err != nil { return err } if !al.Equals(ac.origin.accessList) { return ac.client.SetAccessList(ac.origin.accessList) } return nil } actionDNSServerConfig = func(ac *actionContext) error { dc, err := ac.client.DNSConfig() if err != nil { return err } // dc.Sanitize(ac.rl) if !dc.Equals(ac.origin.dnsConfig) { if err = ac.client.SetDNSConfig(ac.origin.dnsConfig); err != nil { return err } } return nil } actionDHCPServerConfig = func(ac *actionContext) error { if ac.origin.dhcpServerConfig.HasConfig() { sc, err := ac.client.DhcpConfig() if err != nil { return err } origClone := ac.origin.dhcpServerConfig.Clone() if ac.replica.InterfaceName != "" { // overwrite interface name origClone.InterfaceName = utils.Ptr(ac.replica.InterfaceName) } if ac.replica.DHCPServerEnabled != nil { // overwrite dhcp enabled origClone.Enabled = ac.replica.DHCPServerEnabled } if !sc.CleanAndEquals(origClone) { return ac.client.SetDhcpConfig(origClone) } } return nil } actionDHCPStaticLeases = func(ac *actionContext) error { sc, err := ac.client.DhcpConfig() if err != nil { return err } a, r := model.MergeDhcpStaticLeases(sc.StaticLeases, ac.origin.dhcpServerConfig.StaticLeases) for _, lease := range r { if err := ac.client.DeleteDHCPStaticLease(lease); err != nil { ac.rl.With("hostname", lease.Hostname, "error", err).Error("error deleting dhcp static lease") if !ac.cfg.ContinueOnError { return err } } } for _, lease := range a { if err := ac.client.AddDHCPStaticLease(lease); err != nil { ac.rl.With("hostname", lease.Hostname, "error", err).Error("error adding dhcp static lease") if !ac.cfg.ContinueOnError { return err } } } return nil } tlsConfig = func(ac *actionContext) error { tlsc, err := ac.client.TLSConfig() if err != nil { return err } if !tlsc.Equals(ac.origin.tlsConfig) { if err := ac.client.SetTLSConfig(ac.origin.tlsConfig); err != nil { ac.rl.With("enabled", ac.origin.tlsConfig.Enabled, "error", err).Error("error setting tls config") if !ac.cfg.ContinueOnError { return err } } } return nil } ) func syncFilterType( rl *zap.SugaredLogger, of *[]model.Filter, rFilters *[]model.Filter, whitelist bool, replica client.Client, continueOnError bool, ) error { fa, fu, fd := model.MergeFilters(rFilters, of) for _, f := range fd { if err := replica.DeleteFilter(whitelist, f); err != nil { rl.With("filter", f.Name, "url", f.Url, "whitelist", whitelist, "error", err).Error("error deleting filter") if !continueOnError { return err } } } for _, f := range fa { if err := replica.AddFilter(whitelist, f); err != nil { rl.With("filter", f.Name, "url", f.Url, "whitelist", whitelist, "error", err).Error("error adding filter") if !continueOnError { return err } } } for _, f := range fu { if err := replica.UpdateFilter(whitelist, f); err != nil { rl.With("filter", f.Name, "url", f.Url, "whitelist", whitelist, "error", err).Error("error updating filter") if !continueOnError { return err } } } if len(fa) > 0 || len(fu) > 0 { if err := replica.RefreshFilters(whitelist); err != nil { return err } } return nil }