mirror of
https://github.com/swissmakers/fail2ban-ui.git
synced 2026-04-17 05:53:15 +02:00
Implement config-change check, before doing reload
This commit is contained in:
@@ -7,13 +7,12 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UISettings holds both the UI settings (like language) and
|
// AppSettings holds both the UI settings (like language) and
|
||||||
// relevant Fail2ban jail/local config options.
|
// relevant Fail2ban jail/local config options.
|
||||||
type UISettings struct {
|
type AppSettings struct {
|
||||||
// UI-specific
|
Language string `json:"language"`
|
||||||
Language string `json:"language"`
|
ReloadNeeded bool `json:"reloadNeeded"`
|
||||||
// Whether a reload is needed (e.g. user changed filter or jail settings).
|
AlertCountries []string `json:"alertCountries"`
|
||||||
ReloadNeeded bool `json:"reloadNeeded"`
|
|
||||||
|
|
||||||
// These mirror some Fail2ban [DEFAULT] section parameters from jail.local
|
// These mirror some Fail2ban [DEFAULT] section parameters from jail.local
|
||||||
BantimeIncrement bool `json:"bantimeIncrement"`
|
BantimeIncrement bool `json:"bantimeIncrement"`
|
||||||
@@ -30,7 +29,7 @@ const settingsFile = "fail2ban-ui-settings.json"
|
|||||||
|
|
||||||
// in-memory copy of settings
|
// in-memory copy of settings
|
||||||
var (
|
var (
|
||||||
currentSettings UISettings
|
currentSettings AppSettings
|
||||||
settingsLock sync.RWMutex
|
settingsLock sync.RWMutex
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -55,9 +54,10 @@ func setDefaults() {
|
|||||||
settingsLock.Lock()
|
settingsLock.Lock()
|
||||||
defer settingsLock.Unlock()
|
defer settingsLock.Unlock()
|
||||||
|
|
||||||
currentSettings = UISettings{
|
currentSettings = AppSettings{
|
||||||
Language: "en",
|
Language: "en",
|
||||||
ReloadNeeded: false,
|
ReloadNeeded: false,
|
||||||
|
AlertCountries: []string{"all"},
|
||||||
|
|
||||||
BantimeIncrement: true,
|
BantimeIncrement: true,
|
||||||
IgnoreIP: "127.0.0.1/8 ::1 172.16.10.1/24",
|
IgnoreIP: "127.0.0.1/8 ::1 172.16.10.1/24",
|
||||||
@@ -79,7 +79,7 @@ func loadSettings() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var s UISettings
|
var s AppSettings
|
||||||
if err := json.Unmarshal(data, &s); err != nil {
|
if err := json.Unmarshal(data, &s); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -103,33 +103,54 @@ func saveSettings() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetSettings returns a copy of the current settings
|
// GetSettings returns a copy of the current settings
|
||||||
func GetSettings() UISettings {
|
func GetSettings() AppSettings {
|
||||||
settingsLock.RLock()
|
settingsLock.RLock()
|
||||||
defer settingsLock.RUnlock()
|
defer settingsLock.RUnlock()
|
||||||
return currentSettings
|
return currentSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateSettings modifies the in-memory settings, sets ReloadNeeded if required, then saves to disk.
|
// MarkReloadNeeded sets reloadNeeded = true and saves JSON
|
||||||
// Optionally, we can detect changes that require a reload vs. changes that don't.
|
func MarkReloadNeeded() error {
|
||||||
func UpdateSettings(new UISettings) (UISettings, error) {
|
|
||||||
settingsLock.Lock()
|
settingsLock.Lock()
|
||||||
defer settingsLock.Unlock()
|
defer settingsLock.Unlock()
|
||||||
|
|
||||||
// If user changed certain fields that require a Fail2ban reload, set ReloadNeeded = true.
|
currentSettings.ReloadNeeded = true
|
||||||
// For example, if any of these fields changed:
|
return saveSettings()
|
||||||
reloadNeededBefore := currentSettings.ReloadNeeded
|
}
|
||||||
|
|
||||||
if currentSettings.BantimeIncrement != new.BantimeIncrement ||
|
// MarkReloadDone sets reloadNeeded = false and saves JSON
|
||||||
currentSettings.IgnoreIP != new.IgnoreIP ||
|
func MarkReloadDone() error {
|
||||||
currentSettings.Bantime != new.Bantime ||
|
settingsLock.Lock()
|
||||||
currentSettings.Findtime != new.Findtime ||
|
defer settingsLock.Unlock()
|
||||||
currentSettings.Maxretry != new.Maxretry ||
|
|
||||||
currentSettings.Destemail != new.Destemail ||
|
currentSettings.ReloadNeeded = false
|
||||||
currentSettings.Sender != new.Sender {
|
return saveSettings()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateSettings merges new settings with old and sets reloadNeeded if needed
|
||||||
|
func UpdateSettings(new AppSettings) (AppSettings, error) {
|
||||||
|
settingsLock.Lock()
|
||||||
|
defer settingsLock.Unlock()
|
||||||
|
|
||||||
|
old := currentSettings
|
||||||
|
|
||||||
|
// If certain fields change, we mark reload needed
|
||||||
|
if old.BantimeIncrement != new.BantimeIncrement ||
|
||||||
|
old.IgnoreIP != new.IgnoreIP ||
|
||||||
|
old.Bantime != new.Bantime ||
|
||||||
|
old.Findtime != new.Findtime ||
|
||||||
|
old.Maxretry != new.Maxretry ||
|
||||||
|
old.Destemail != new.Destemail ||
|
||||||
|
old.Sender != new.Sender {
|
||||||
new.ReloadNeeded = true
|
new.ReloadNeeded = true
|
||||||
} else {
|
} else {
|
||||||
// preserve previous ReloadNeeded if it was already true
|
// preserve previous ReloadNeeded if it was already true
|
||||||
new.ReloadNeeded = new.ReloadNeeded || reloadNeededBefore
|
new.ReloadNeeded = new.ReloadNeeded || old.ReloadNeeded
|
||||||
|
}
|
||||||
|
|
||||||
|
// Countries change? Currently also requires a reload
|
||||||
|
if !equalStringSlices(old.AlertCountries, new.AlertCountries) {
|
||||||
|
new.ReloadNeeded = true
|
||||||
}
|
}
|
||||||
|
|
||||||
currentSettings = new
|
currentSettings = new
|
||||||
@@ -141,10 +162,18 @@ func UpdateSettings(new UISettings) (UISettings, error) {
|
|||||||
return currentSettings, nil
|
return currentSettings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarkReloadDone sets ReloadNeeded = false after the user reloaded fail2ban
|
func equalStringSlices(a, b []string) bool {
|
||||||
func MarkReloadDone() error {
|
if len(a) != len(b) {
|
||||||
settingsLock.Lock()
|
return false
|
||||||
defer settingsLock.Unlock()
|
}
|
||||||
currentSettings.ReloadNeeded = false
|
m := make(map[string]bool)
|
||||||
return saveSettings()
|
for _, x := range a {
|
||||||
|
m[x] = false
|
||||||
|
}
|
||||||
|
for _, x := range b {
|
||||||
|
if _, ok := m[x]; !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user