From 103d78d0ee99b6eae99a3a81122b4f95fe4daa19 Mon Sep 17 00:00:00 2001 From: bakito Date: Mon, 1 Nov 2021 18:20:14 +0100 Subject: [PATCH] implement other feature flags --- README.md | 27 +++++- cmd/root.go | 9 ++ cmd/run.go | 19 ++++ pkg/sync/sync.go | 207 ++++++++++++++++++++++-------------------- pkg/sync/sync_test.go | 30 ++++++ pkg/types/features.go | 16 +++- pkg/types/types.go | 5 - 7 files changed, 208 insertions(+), 105 deletions(-) diff --git a/README.md b/README.md index 16ef7c7..3f21be5 100644 --- a/README.md +++ b/README.md @@ -107,8 +107,19 @@ services: - CRON=*/10 * * * * # run every 10 minutes - RUNONSTART=true # Configure sync features; by default all features are enabled. - # - FEATURES_DHCP_SERVERCONFIG=false - # - FEATURES_DHCP_STATICLEASES=false + # - FEATURES_GENERALSETTINGS=true + # - FEATURES_QUERYLOGCONFIG=true + # - FEATURES_STATSCONFIG=true + # - FEATURES_CLIENTSETTINGS=true + # - FEATURES_SERVICES=true + # - FEATURES_FILTERS=true + + # - FEATURES_DHCP_SERVERCONFIG=true + # - FEATURES_DHCP_STATICLEASES=true + + # - FEATURES_DNS_SERVERCONFIG=true + # - FEATURES_DNS_ACCESSLISTS=true + # - FEATURES_DNS_REWRITES=true ports: - 8080:8080 restart: unless-stopped @@ -161,9 +172,19 @@ api: # Configure sync features; by default all features are enabled. features: + generalSettings: true + queryLogConfig: true + statsConfig: true + clientSettings: true + services: true + filters: true dhcp: - serverConfig: false + serverConfig: true staticLeases: true + dns: + serverConfig: true + accessLists: true + rewrites: true ``` ## Log Level diff --git a/cmd/root.go b/cmd/root.go index c37b0e7..8523568 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -24,6 +24,15 @@ const ( configFeatureDHCPServerConfig = "features.dhcp.serverConfig" configFeatureDHCPStaticLeases = "features.dhcp.staticLeases" + configFeatureDNServerConfig = "features.dns.serverConfig" + configFeatureDNSPAccessLists = "features.dns.accessLists" + configFeatureDNSRewrites = "features.dns.rewrites" + configFeatureGeneralSettings = "features.generalSettings" + configFeatureQueryLogConfig = "features.queryLogConfig" + configFeatureStatsConfig = "features.statsConfig" + configFeatureClientSettings = "features.clientSettings" + configFeatureServices = "features.services" + configFeatureFilters = "features.filters" configOriginURL = "origin.url" configOriginAPIPath = "origin.apiPath" diff --git a/cmd/run.go b/cmd/run.go index 7763ecb..9de959b 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -42,6 +42,25 @@ func init() { doCmd.PersistentFlags().Bool("feature-dhcp-static-leases", true, "Enable DHCP server static leases feature") _ = viper.BindPFlag(configFeatureDHCPStaticLeases, doCmd.PersistentFlags().Lookup("feature-dhcp-static-leases")) + doCmd.PersistentFlags().Bool("feature-dns-server-config", true, "Enable DNS server config feature") + _ = viper.BindPFlag(configFeatureDNServerConfig, doCmd.PersistentFlags().Lookup("feature-dns-server-config")) + doCmd.PersistentFlags().Bool("feature-dns-access-lists", true, "Enable DNS server access lists feature") + _ = viper.BindPFlag(configFeatureDNSPAccessLists, doCmd.PersistentFlags().Lookup("feature-dns-access-lists")) + doCmd.PersistentFlags().Bool("feature-dns-rewrites", true, "Enable DNS rewrites feature") + _ = viper.BindPFlag(configFeatureDNSRewrites, doCmd.PersistentFlags().Lookup("feature-dns-rewrites")) + doCmd.PersistentFlags().Bool("feature-general-settings", true, "Enable general settings feature") + _ = viper.BindPFlag(configFeatureGeneralSettings, doCmd.PersistentFlags().Lookup("feature-general-settings")) + doCmd.PersistentFlags().Bool("feature-query-log-config", true, "Enable query log config feature") + _ = viper.BindPFlag(configFeatureQueryLogConfig, doCmd.PersistentFlags().Lookup("feature-query-log-config")) + doCmd.PersistentFlags().Bool("feature-stats-config", true, "Enable stats config feature") + _ = viper.BindPFlag(configFeatureStatsConfig, doCmd.PersistentFlags().Lookup("feature-stats-config")) + doCmd.PersistentFlags().Bool("feature-client-settings", true, "Enable client settings feature") + _ = viper.BindPFlag(configFeatureClientSettings, doCmd.PersistentFlags().Lookup("feature-client-settings")) + doCmd.PersistentFlags().Bool("feature-services", true, "Enable services sync feature") + _ = viper.BindPFlag(configFeatureServices, doCmd.PersistentFlags().Lookup("feature-services")) + doCmd.PersistentFlags().Bool("feature-filters", true, "Enable filters sync feature") + _ = viper.BindPFlag(configFeatureFilters, doCmd.PersistentFlags().Lookup("feature-filters")) + doCmd.PersistentFlags().String("beta", "", "Enable beta features (comma separated list)") _ = viper.BindPFlag(configBeta, doCmd.PersistentFlags().Lookup("beta")) diff --git a/pkg/sync/sync.go b/pkg/sync/sync.go index eded458..845ae5e 100644 --- a/pkg/sync/sync.go +++ b/pkg/sync/sync.go @@ -257,40 +257,44 @@ func (w *worker) statusWithSetup(rl *zap.SugaredLogger, replica types.AdGuardIns } func (w *worker) syncServices(os types.Services, replica client.Client) error { - rs, err := replica.Services() - if err != nil { - return err - } - - if !os.Equals(rs) { - if err := replica.SetServices(os); err != nil { + if w.cfg.Features.Services { + rs, err := replica.Services() + if err != nil { return err } + + if !os.Equals(rs) { + if err := replica.SetServices(os); err != nil { + return err + } + } } return nil } func (w *worker) syncFilters(of *types.FilteringStatus, replica client.Client) error { - rf, err := replica.Filtering() - if err != nil { - return err - } - - if err = w.syncFilterType(of.Filters, rf.Filters, false, replica); err != nil { - return err - } - if err = w.syncFilterType(of.WhitelistFilters, rf.WhitelistFilters, true, replica); err != nil { - return err - } - - if of.UserRules.String() != rf.UserRules.String() { - return replica.SetCustomRules(of.UserRules) - } - - if of.Enabled != rf.Enabled || of.Interval != rf.Interval { - if err = replica.ToggleFiltering(of.Enabled, of.Interval); err != nil { + if w.cfg.Features.Filters { + rf, err := replica.Filtering() + if err != nil { return err } + + if err = w.syncFilterType(of.Filters, rf.Filters, false, replica); err != nil { + return err + } + if err = w.syncFilterType(of.WhitelistFilters, rf.WhitelistFilters, true, replica); err != nil { + return err + } + + if of.UserRules.String() != rf.UserRules.String() { + return replica.SetCustomRules(of.UserRules) + } + + if of.Enabled != rf.Enabled || of.Interval != rf.Interval { + if err = replica.ToggleFiltering(of.Enabled, of.Interval); err != nil { + return err + } + } } return nil } @@ -318,121 +322,132 @@ func (w *worker) syncFilterType(of types.Filters, rFilters types.Filters, whitel } func (w *worker) syncRewrites(rl *zap.SugaredLogger, or *types.RewriteEntries, replica client.Client) error { + if w.cfg.Features.DNS.Rewrites { + replicaRewrites, err := replica.RewriteList() + if err != nil { + return err + } - replicaRewrites, err := replica.RewriteList() - if err != nil { - return err - } + a, r, d := replicaRewrites.Merge(or) - a, r, d := replicaRewrites.Merge(or) + if err = replica.AddRewriteEntries(a...); err != nil { + return err + } + if err = replica.DeleteRewriteEntries(r...); err != nil { + return err + } - if err = replica.AddRewriteEntries(a...); err != nil { - return err - } - if err = replica.DeleteRewriteEntries(r...); err != nil { - return err - } - - for _, dupl := range d { - rl.With("domain", dupl.Domain, "answer", dupl.Answer).Warn("Skipping duplicated rewrite from source") + for _, dupl := range d { + rl.With("domain", dupl.Domain, "answer", dupl.Answer).Warn("Skipping duplicated rewrite from source") + } } return nil } func (w *worker) syncClients(oc *types.Clients, replica client.Client) error { - rc, err := replica.Clients() - if err != nil { - return err - } + if w.cfg.Features.ClientSettings { + rc, err := replica.Clients() + if err != nil { + return err + } - a, u, r := rc.Merge(oc) + a, u, r := rc.Merge(oc) - if err = replica.AddClients(a...); err != nil { - return err - } - if err = replica.UpdateClients(u...); err != nil { - return err - } - if err = replica.DeleteClients(r...); err != nil { - return err + if err = replica.AddClients(a...); err != nil { + return err + } + if err = replica.UpdateClients(u...); err != nil { + return err + } + if err = replica.DeleteClients(r...); err != nil { + return err + } } return nil } func (w *worker) syncGeneralSettings(o *origin, rs *types.Status, replica client.Client) error { - if o.status.ProtectionEnabled != rs.ProtectionEnabled { - if err := replica.ToggleProtection(o.status.ProtectionEnabled); err != nil { - return err + if w.cfg.Features.GeneralSettings { + if o.status.ProtectionEnabled != rs.ProtectionEnabled { + if err := replica.ToggleProtection(o.status.ProtectionEnabled); err != nil { + return err + } } - } - if rp, err := replica.Parental(); err != nil { - return err - } else if o.parental != rp { - if err = replica.ToggleParental(o.parental); err != nil { + if rp, err := replica.Parental(); err != nil { return err + } else if o.parental != rp { + if err = replica.ToggleParental(o.parental); err != nil { + return err + } } - } - if rs, err := replica.SafeSearch(); err != nil { - return err - } else if o.safeSearch != rs { - if err = replica.ToggleSafeSearch(o.safeSearch); err != nil { + if rs, err := replica.SafeSearch(); err != nil { return err + } else if o.safeSearch != rs { + if err = replica.ToggleSafeSearch(o.safeSearch); err != nil { + return err + } } - } - if rs, err := replica.SafeBrowsing(); err != nil { - return err - } else if o.safeBrowsing != rs { - if err = replica.ToggleSafeBrowsing(o.safeBrowsing); err != nil { + if rs, err := replica.SafeBrowsing(); err != nil { return err + } else if o.safeBrowsing != rs { + if err = replica.ToggleSafeBrowsing(o.safeBrowsing); err != nil { + return err + } } } return nil } func (w *worker) syncConfigs(o *origin, rc client.Client) error { - qlc, err := rc.QueryLogConfig() - if err != nil { - return err - } - if !o.queryLogConfig.Equals(qlc) { - if err = rc.SetQueryLogConfig(o.queryLogConfig.Enabled, o.queryLogConfig.Interval, o.queryLogConfig.AnonymizeClientIP); err != nil { + if w.cfg.Features.QueryLogConfig { + qlc, err := rc.QueryLogConfig() + if err != nil { return err } + if !o.queryLogConfig.Equals(qlc) { + if err = rc.SetQueryLogConfig(o.queryLogConfig.Enabled, o.queryLogConfig.Interval, o.queryLogConfig.AnonymizeClientIP); err != nil { + return err + } + } } - - sc, err := rc.StatsConfig() - if err != nil { - return err - } - if o.statsConfig.Interval != sc.Interval { - if err = rc.SetStatsConfig(o.statsConfig.Interval); err != nil { + if w.cfg.Features.StatsConfig { + sc, err := rc.StatsConfig() + if err != nil { return err } + if o.statsConfig.Interval != sc.Interval { + if err = rc.SetStatsConfig(o.statsConfig.Interval); err != nil { + return err + } + } } return nil } func (w *worker) syncDNS(oal *types.AccessList, odc *types.DNSConfig, rc client.Client) error { - al, err := rc.AccessList() - if err != nil { - return err - } - if !al.Equals(oal) { - if err = rc.SetAccessList(oal); err != nil { + if w.cfg.Features.DNS.AccessLists { + al, err := rc.AccessList() + if err != nil { return err } + if !al.Equals(oal) { + if err = rc.SetAccessList(oal); err != nil { + return err + } + } } - - dc, err := rc.DNSConfig() - if err != nil { - return err - } - if !dc.Equals(odc) { - if err = rc.SetDNSConfig(odc); err != nil { + if w.cfg.Features.DNS.ServerConfig { + dc, err := rc.DNSConfig() + if err != nil { return err } + if !dc.Equals(odc) { + if err = rc.SetDNSConfig(odc); err != nil { + return err + } + } } return nil } diff --git a/pkg/sync/sync_test.go b/pkg/sync/sync_test.go index 036a746..e5d4445 100644 --- a/pkg/sync/sync_test.go +++ b/pkg/sync/sync_test.go @@ -28,6 +28,25 @@ var _ = Describe("Sync", func() { createClient: func(instance types.AdGuardInstance) (client.Client, error) { return cl, nil }, + cfg: &types.Config{ + Features: types.Features{ + DHCP: types.DHCP{ + ServerConfig: true, + StaticLeases: true, + }, + DNS: types.DNS{ + ServerConfig: true, + Rewrites: true, + AccessLists: true, + }, + Filters: true, + ClientSettings: true, + Services: true, + GeneralSettings: true, + StatsConfig: true, + QueryLogConfig: true, + }, + }, } te = errors.New(uuid.NewString()) }) @@ -417,6 +436,17 @@ var _ = Describe("Sync", func() { ServerConfig: true, StaticLeases: true, }, + DNS: types.DNS{ + ServerConfig: true, + Rewrites: true, + AccessLists: true, + }, + Filters: true, + ClientSettings: true, + Services: true, + GeneralSettings: true, + StatsConfig: true, + QueryLogConfig: true, }, } // origin diff --git a/pkg/types/features.go b/pkg/types/features.go index 22425e8..aa799bf 100644 --- a/pkg/types/features.go +++ b/pkg/types/features.go @@ -8,7 +8,14 @@ import ( // Features feature flags type Features struct { - DHCP DHCP `json:"dhcp" yaml:"dhcp"` + DNS DNS `json:"dns" yaml:"dns"` + DHCP DHCP `json:"dhcp" yaml:"dhcp"` + GeneralSettings bool `json:"generalSettings" yaml:"generalSettings"` + QueryLogConfig bool `json:"queryLogConfig" yaml:"queryLogConfig"` + StatsConfig bool `json:"statsConfig" yaml:"statsConfig"` + ClientSettings bool `json:"clientSettings" yaml:"clientSettings"` + Services bool `json:"services" yaml:"services"` + Filters bool `json:"filters" yaml:"filters"` } // DHCP features @@ -17,6 +24,13 @@ type DHCP struct { StaticLeases bool `json:"staticLeases" yaml:"staticLeases"` } +// DNS features +type DNS struct { + AccessLists bool `json:"accessLists" yaml:"accessLists"` + ServerConfig bool `json:"serverConfig" yaml:"serverConfig"` + Rewrites bool `json:"rewrites" yaml:"rewrites"` +} + func (f *Features) LogDisabled(l *zap.SugaredLogger) { var features []string if !f.DHCP.ServerConfig { diff --git a/pkg/types/types.go b/pkg/types/types.go index 7242694..547d3db 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -5,7 +5,6 @@ import ( "fmt" "sort" "strings" - "sync" ) const ( @@ -13,10 +12,6 @@ const ( DefaultAPIPath = "/control" ) -var ( - doOnce sync.Once -) - // Config application configuration struct type Config struct { Origin AdGuardInstance `json:"origin" yaml:"origin"`