implement other feature flags

This commit is contained in:
bakito 2021-11-01 18:20:14 +01:00
parent ad64fdeda6
commit 103d78d0ee
No known key found for this signature in database
GPG key ID: FAF93C1C384DD6B4
7 changed files with 208 additions and 105 deletions

View file

@ -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

View file

@ -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"

View file

@ -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"))

View file

@ -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
}

View file

@ -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

View file

@ -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 {

View file

@ -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"`