mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-16 07:16:38 +00:00
Add method to track and merge default interface blacklist entries
Introduce `mergeDefaultIFaceBlacklist` to ensure new defaults are appended to the interface blacklist while preserving user modifications. Add tests to verify behavior, including migration of old configs and handling of user-removed entries.
This commit is contained in:
@@ -100,6 +100,7 @@ type Config struct {
|
||||
WgPort int
|
||||
NetworkMonitor *bool
|
||||
IFaceBlackList []string
|
||||
IFaceBlackListAppliedDefaults []string `json:",omitempty"`
|
||||
DisableIPv6Discovery bool
|
||||
RosenpassEnabled bool
|
||||
RosenpassPermissive bool
|
||||
@@ -359,10 +360,7 @@ func (config *Config) apply(input ConfigInput) (updated bool, err error) {
|
||||
updated = true
|
||||
}
|
||||
|
||||
if len(config.IFaceBlackList) == 0 {
|
||||
log.Infof("filling in interface blacklist with defaults: [ %s ]",
|
||||
strings.Join(DefaultInterfaceBlacklist, " "))
|
||||
config.IFaceBlackList = append(config.IFaceBlackList, DefaultInterfaceBlacklist...)
|
||||
if changed := config.mergeDefaultIFaceBlacklist(); changed {
|
||||
updated = true
|
||||
}
|
||||
|
||||
@@ -596,6 +594,37 @@ func (config *Config) apply(input ConfigInput) (updated bool, err error) {
|
||||
return updated, nil
|
||||
}
|
||||
|
||||
// mergeDefaultIFaceBlacklist ensures that new entries added to DefaultInterfaceBlacklist
|
||||
// are merged into an existing IFaceBlackList on upgrade, while respecting entries that
|
||||
// the user deliberately removed. It tracks which defaults have been offered via
|
||||
// IFaceBlackListAppliedDefaults so removals are not undone.
|
||||
func (config *Config) mergeDefaultIFaceBlacklist() (updated bool) {
|
||||
if len(config.IFaceBlackList) == 0 {
|
||||
log.Infof("filling in interface blacklist with defaults: [ %s ]",
|
||||
strings.Join(DefaultInterfaceBlacklist, " "))
|
||||
config.IFaceBlackList = append(config.IFaceBlackList, DefaultInterfaceBlacklist...)
|
||||
config.IFaceBlackListAppliedDefaults = append([]string{}, DefaultInterfaceBlacklist...)
|
||||
return true
|
||||
}
|
||||
|
||||
// Find defaults not yet tracked in AppliedDefaults — these are genuinely new.
|
||||
// Entries already in AppliedDefaults were either kept or deliberately removed by the user.
|
||||
newDefaults := util.SliceDiff(DefaultInterfaceBlacklist, config.IFaceBlackListAppliedDefaults)
|
||||
if len(newDefaults) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
// Only add entries not already present in the blacklist (avoid duplicates)
|
||||
toAdd := util.SliceDiff(newDefaults, config.IFaceBlackList)
|
||||
if len(toAdd) > 0 {
|
||||
log.Infof("merging new default interface blacklist entries: [ %s ]",
|
||||
strings.Join(toAdd, " "))
|
||||
config.IFaceBlackList = append(config.IFaceBlackList, toAdd...)
|
||||
}
|
||||
config.IFaceBlackListAppliedDefaults = append(config.IFaceBlackListAppliedDefaults, newDefaults...)
|
||||
return true
|
||||
}
|
||||
|
||||
// parseURL parses and validates a service URL
|
||||
func parseURL(serviceName, serviceURL string) (*url.URL, error) {
|
||||
parsedMgmtURL, err := url.ParseRequestURI(serviceURL)
|
||||
|
||||
@@ -108,6 +108,87 @@ func TestExtraIFaceBlackList(t *testing.T) {
|
||||
assert.Contains(t, readConf.(*Config).IFaceBlackList, "eth1")
|
||||
}
|
||||
|
||||
func TestIFaceBlackListMigratesNewDefaults(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
configPath := filepath.Join(tempDir, "config.json")
|
||||
|
||||
// Create a config that simulates an old install with a partial IFaceBlackList
|
||||
// (missing the newer CNI entries like "cilium_", "cali", etc.)
|
||||
config, err := UpdateOrCreateConfig(ConfigInput{
|
||||
ConfigPath: configPath,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Simulate an old config that predates AppliedDefaults tracking:
|
||||
// it has only the original entries, no CNI prefixes, and no AppliedDefaults.
|
||||
oldList := []string{iface.WgInterfaceDefault, "wt", "utun", "tun0", "zt", "ZeroTier", "wg", "ts",
|
||||
"Tailscale", "tailscale", "docker", "veth", "br-", "lo"}
|
||||
config.IFaceBlackList = oldList
|
||||
config.IFaceBlackListAppliedDefaults = nil
|
||||
err = WriteOutConfig(configPath, config)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Re-read the config — apply() should merge in missing defaults
|
||||
reloaded, err := GetConfig(configPath)
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, entry := range DefaultInterfaceBlacklist {
|
||||
assert.Contains(t, reloaded.IFaceBlackList, entry,
|
||||
"IFaceBlackList should contain default entry %q after migration", entry)
|
||||
}
|
||||
|
||||
// Verify no duplicates were introduced
|
||||
seen := make(map[string]bool)
|
||||
for _, entry := range reloaded.IFaceBlackList {
|
||||
assert.False(t, seen[entry], "duplicate entry %q in IFaceBlackList", entry)
|
||||
seen[entry] = true
|
||||
}
|
||||
|
||||
// AppliedDefaults should now track all current defaults
|
||||
for _, entry := range DefaultInterfaceBlacklist {
|
||||
assert.Contains(t, reloaded.IFaceBlackListAppliedDefaults, entry,
|
||||
"AppliedDefaults should track %q", entry)
|
||||
}
|
||||
|
||||
// Re-read again — should not change (idempotent)
|
||||
reloaded2, err := GetConfig(configPath)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, reloaded.IFaceBlackList, reloaded2.IFaceBlackList,
|
||||
"IFaceBlackList should be stable on subsequent reads")
|
||||
}
|
||||
|
||||
func TestIFaceBlackListRespectsUserRemoval(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
configPath := filepath.Join(tempDir, "config.json")
|
||||
|
||||
// Create a fresh config (all defaults applied)
|
||||
config, err := UpdateOrCreateConfig(ConfigInput{
|
||||
ConfigPath: configPath,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, config.IFaceBlackList, "cali")
|
||||
|
||||
// User deliberately removes "cali" from their blacklist
|
||||
filtered := make([]string, 0, len(config.IFaceBlackList))
|
||||
for _, entry := range config.IFaceBlackList {
|
||||
if entry != "cali" {
|
||||
filtered = append(filtered, entry)
|
||||
}
|
||||
}
|
||||
config.IFaceBlackList = filtered
|
||||
err = WriteOutConfig(configPath, config)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Re-read — "cali" should NOT be re-added because it's in AppliedDefaults
|
||||
reloaded, err := GetConfig(configPath)
|
||||
require.NoError(t, err)
|
||||
assert.NotContains(t, reloaded.IFaceBlackList, "cali",
|
||||
"user-removed entry should not be re-added")
|
||||
|
||||
// AppliedDefaults should still contain "cali" (it was offered)
|
||||
assert.Contains(t, reloaded.IFaceBlackListAppliedDefaults, "cali")
|
||||
}
|
||||
|
||||
func TestHiddenPreSharedKey(t *testing.T) {
|
||||
hidden := "**********"
|
||||
samplePreSharedKey := "mysecretpresharedkey"
|
||||
|
||||
Reference in New Issue
Block a user