[management] set components network map by default and optimize memory usage (#5575)

* Network map now defaults to compacted mode at startup; environment parsing issues yield clearer warnings and disabling compacted mode is logged.

* **Bug Fixes**
  * DNS enablement and nameserver selection now correctly respect group membership, reducing incorrect DNS assignments.

* **Refactor**
  * Internal routing and firewall rule generation streamlined for more consistent rule IDs and safer peer handling.

* **Performance**
  * Minor memory and slice allocation improvements for peer/group processing.
This commit is contained in:
Vlad
2026-03-11 18:19:17 +01:00
committed by GitHub
parent 7a23c57cf8
commit b5489d4986
3 changed files with 51 additions and 83 deletions

View File

@@ -87,9 +87,14 @@ func NewController(ctx context.Context, store store.Store, metrics telemetry.App
newNetworkMapBuilder = false newNetworkMapBuilder = false
} }
compactedNetworkMap, err := strconv.ParseBool(os.Getenv(types.EnvNewNetworkMapCompacted)) compactedNetworkMap := true
if err != nil { compactedEnv := os.Getenv(types.EnvNewNetworkMapCompacted)
log.WithContext(ctx).Warnf("failed to parse %s, using default value false: %v", types.EnvNewNetworkMapCompacted, err) parsedCompactedNmap, err := strconv.ParseBool(compactedEnv)
if err != nil && len(compactedEnv) > 0 {
log.WithContext(ctx).Warnf("failed to parse %s, using default value true: %v", types.EnvNewNetworkMapCompacted, err)
}
if err == nil && !parsedCompactedNmap {
log.WithContext(ctx).Info("disabling compacted mode")
compactedNetworkMap = false compactedNetworkMap = false
} }

View File

@@ -368,7 +368,7 @@ func (a *Account) getPeersGroupsPoliciesRoutes(
func (a *Account) getPeersFromGroups(ctx context.Context, groups []string, peerID string, sourcePostureChecksIDs []string, func (a *Account) getPeersFromGroups(ctx context.Context, groups []string, peerID string, sourcePostureChecksIDs []string,
validatedPeersMap map[string]struct{}, postureFailedPeers *map[string]map[string]struct{}) ([]string, bool) { validatedPeersMap map[string]struct{}, postureFailedPeers *map[string]map[string]struct{}) ([]string, bool) {
peerInGroups := false peerInGroups := false
filteredPeerIDs := make([]string, 0, len(a.Peers)) filteredPeerIDs := make([]string, 0, len(groups))
seenPeerIds := make(map[string]struct{}, len(groups)) seenPeerIds := make(map[string]struct{}, len(groups))
for _, gid := range groups { for _, gid := range groups {
@@ -378,7 +378,7 @@ func (a *Account) getPeersFromGroups(ctx context.Context, groups []string, peerI
} }
if group.IsGroupAll() || len(groups) == 1 { if group.IsGroupAll() || len(groups) == 1 {
filteredPeerIDs = filteredPeerIDs[:0] filteredPeerIDs = make([]string, 0, len(group.Peers))
peerInGroups = false peerInGroups = false
for _, pid := range group.Peers { for _, pid := range group.Peers {
peer, ok := a.Peers[pid] peer, ok := a.Peers[pid]

View File

@@ -134,7 +134,7 @@ func (c *NetworkMapComponents) Calculate(ctx context.Context) *NetworkMap {
sourcePeers, sourcePeers,
) )
dnsManagementStatus := c.getPeerDNSManagementStatus(targetPeerID) dnsManagementStatus := c.getPeerDNSManagementStatusFromGroups(peerGroups)
dnsUpdate := nbdns.Config{ dnsUpdate := nbdns.Config{
ServiceEnable: dnsManagementStatus, ServiceEnable: dnsManagementStatus,
} }
@@ -152,7 +152,7 @@ func (c *NetworkMapComponents) Calculate(ctx context.Context) *NetworkMap {
customZones = append(customZones, c.AccountZones...) customZones = append(customZones, c.AccountZones...)
dnsUpdate.CustomZones = customZones dnsUpdate.CustomZones = customZones
dnsUpdate.NameServerGroups = c.getPeerNSGroups(targetPeerID) dnsUpdate.NameServerGroups = c.getPeerNSGroupsFromGroups(targetPeerID, peerGroups)
} }
return &NetworkMap{ return &NetworkMap{
@@ -278,6 +278,16 @@ func (c *NetworkMapComponents) connResourcesGenerator(targetPeer *nbpeer.Peer) (
peers := make([]*nbpeer.Peer, 0) peers := make([]*nbpeer.Peer, 0)
return func(rule *PolicyRule, groupPeers []*nbpeer.Peer, direction int) { return func(rule *PolicyRule, groupPeers []*nbpeer.Peer, direction int) {
protocol := rule.Protocol
if protocol == PolicyRuleProtocolNetbirdSSH {
protocol = PolicyRuleProtocolTCP
}
protocolStr := string(protocol)
actionStr := string(rule.Action)
dirStr := strconv.Itoa(direction)
portsJoined := strings.Join(rule.Ports, ",")
for _, peer := range groupPeers { for _, peer := range groupPeers {
if peer == nil { if peer == nil {
continue continue
@@ -288,21 +298,18 @@ func (c *NetworkMapComponents) connResourcesGenerator(targetPeer *nbpeer.Peer) (
peersExists[peer.ID] = struct{}{} peersExists[peer.ID] = struct{}{}
} }
protocol := rule.Protocol peerIP := net.IP(peer.IP).String()
if protocol == PolicyRuleProtocolNetbirdSSH {
protocol = PolicyRuleProtocolTCP
}
fr := FirewallRule{ fr := FirewallRule{
PolicyID: rule.ID, PolicyID: rule.ID,
PeerIP: net.IP(peer.IP).String(), PeerIP: peerIP,
Direction: direction, Direction: direction,
Action: string(rule.Action), Action: actionStr,
Protocol: string(protocol), Protocol: protocolStr,
} }
ruleID := rule.ID + fr.PeerIP + strconv.Itoa(direction) + ruleID := rule.ID + peerIP + dirStr +
fr.Protocol + fr.Action + strings.Join(rule.Ports, ",") protocolStr + actionStr + portsJoined
if _, ok := rulesExists[ruleID]; ok { if _, ok := rulesExists[ruleID]; ok {
continue continue
} }
@@ -313,13 +320,7 @@ func (c *NetworkMapComponents) connResourcesGenerator(targetPeer *nbpeer.Peer) (
continue continue
} }
rules = append(rules, expandPortsAndRanges(fr, &PolicyRule{ rules = append(rules, expandPortsAndRanges(fr, rule, targetPeer)...)
ID: rule.ID,
Ports: rule.Ports,
PortRanges: rule.PortRanges,
Protocol: rule.Protocol,
Action: rule.Action,
}, targetPeer)...)
} }
}, func() ([]*nbpeer.Peer, []*FirewallRule) { }, func() ([]*nbpeer.Peer, []*FirewallRule) {
return peers, rules return peers, rules
@@ -395,7 +396,7 @@ func (c *NetworkMapComponents) getPeerFromResource(resource Resource, peerID str
} }
func (c *NetworkMapComponents) filterPeersByLoginExpiration(aclPeers []*nbpeer.Peer) ([]*nbpeer.Peer, []*nbpeer.Peer) { func (c *NetworkMapComponents) filterPeersByLoginExpiration(aclPeers []*nbpeer.Peer) ([]*nbpeer.Peer, []*nbpeer.Peer) {
var peersToConnect []*nbpeer.Peer peersToConnect := make([]*nbpeer.Peer, 0, len(aclPeers))
var expiredPeers []*nbpeer.Peer var expiredPeers []*nbpeer.Peer
for _, p := range aclPeers { for _, p := range aclPeers {
@@ -410,35 +411,35 @@ func (c *NetworkMapComponents) filterPeersByLoginExpiration(aclPeers []*nbpeer.P
return peersToConnect, expiredPeers return peersToConnect, expiredPeers
} }
func (c *NetworkMapComponents) getPeerDNSManagementStatus(peerID string) bool { func (c *NetworkMapComponents) getPeerDNSManagementStatusFromGroups(peerGroups map[string]struct{}) bool {
peerGroups := c.GetPeerGroups(peerID)
enabled := true
for _, groupID := range c.DNSSettings.DisabledManagementGroups { for _, groupID := range c.DNSSettings.DisabledManagementGroups {
if _, found := peerGroups[groupID]; found { if _, found := peerGroups[groupID]; found {
enabled = false return false
break
} }
} }
return enabled return true
} }
func (c *NetworkMapComponents) getPeerNSGroups(peerID string) []*nbdns.NameServerGroup { func (c *NetworkMapComponents) getPeerNSGroupsFromGroups(peerID string, groupList map[string]struct{}) []*nbdns.NameServerGroup {
groupList := c.GetPeerGroups(peerID)
var peerNSGroups []*nbdns.NameServerGroup var peerNSGroups []*nbdns.NameServerGroup
targetPeerInfo := c.GetPeerInfo(peerID)
if targetPeerInfo == nil {
return peerNSGroups
}
peerIPStr := targetPeerInfo.IP.String()
for _, nsGroup := range c.NameServerGroups { for _, nsGroup := range c.NameServerGroups {
if !nsGroup.Enabled { if !nsGroup.Enabled {
continue continue
} }
for _, gID := range nsGroup.Groups { for _, gID := range nsGroup.Groups {
_, found := groupList[gID] if _, found := groupList[gID]; found {
if found { if !c.peerIsNameserver(peerIPStr, nsGroup) {
targetPeerInfo := c.GetPeerInfo(peerID)
if targetPeerInfo != nil && !c.peerIsNameserver(targetPeerInfo, nsGroup) {
peerNSGroups = append(peerNSGroups, nsGroup.Copy()) peerNSGroups = append(peerNSGroups, nsGroup.Copy())
break
} }
break
} }
} }
} }
@@ -446,9 +447,9 @@ func (c *NetworkMapComponents) getPeerNSGroups(peerID string) []*nbdns.NameServe
return peerNSGroups return peerNSGroups
} }
func (c *NetworkMapComponents) peerIsNameserver(peerInfo *nbpeer.Peer, nsGroup *nbdns.NameServerGroup) bool { func (c *NetworkMapComponents) peerIsNameserver(peerIPStr string, nsGroup *nbdns.NameServerGroup) bool {
for _, ns := range nsGroup.NameServers { for _, ns := range nsGroup.NameServers {
if peerInfo.IP.String() == ns.IP.String() { if peerIPStr == ns.IP.String() {
return true return true
} }
} }
@@ -489,14 +490,13 @@ func (c *NetworkMapComponents) getRoutingPeerRoutes(peerID string) (enabledRoute
} }
seenRoute[r.ID] = struct{}{} seenRoute[r.ID] = struct{}{}
routeObj := c.copyRoute(r) r.Peer = peerInfo.Key
routeObj.Peer = peerInfo.Key
if r.Enabled { if r.Enabled {
enabledRoutes = append(enabledRoutes, routeObj) enabledRoutes = append(enabledRoutes, r)
return return
} }
disabledRoutes = append(disabledRoutes, routeObj) disabledRoutes = append(disabledRoutes, r)
} }
for _, r := range c.Routes { for _, r := range c.Routes {
@@ -510,7 +510,7 @@ func (c *NetworkMapComponents) getRoutingPeerRoutes(peerID string) (enabledRoute
continue continue
} }
newPeerRoute := c.copyRoute(r) newPeerRoute := r.Copy()
newPeerRoute.Peer = id newPeerRoute.Peer = id
newPeerRoute.PeerGroups = nil newPeerRoute.PeerGroups = nil
newPeerRoute.ID = route.ID(string(r.ID) + ":" + id) newPeerRoute.ID = route.ID(string(r.ID) + ":" + id)
@@ -519,50 +519,13 @@ func (c *NetworkMapComponents) getRoutingPeerRoutes(peerID string) (enabledRoute
} }
} }
if r.Peer == peerID { if r.Peer == peerID {
takeRoute(c.copyRoute(r)) takeRoute(r.Copy())
} }
} }
return enabledRoutes, disabledRoutes return enabledRoutes, disabledRoutes
} }
func (c *NetworkMapComponents) copyRoute(r *route.Route) *route.Route {
var groups, accessControlGroups, peerGroups []string
var domains domain.List
if r.Groups != nil {
groups = append([]string{}, r.Groups...)
}
if r.AccessControlGroups != nil {
accessControlGroups = append([]string{}, r.AccessControlGroups...)
}
if r.PeerGroups != nil {
peerGroups = append([]string{}, r.PeerGroups...)
}
if r.Domains != nil {
domains = append(domain.List{}, r.Domains...)
}
return &route.Route{
ID: r.ID,
AccountID: r.AccountID,
Network: r.Network,
NetworkType: r.NetworkType,
Description: r.Description,
Peer: r.Peer,
PeerID: r.PeerID,
Metric: r.Metric,
Masquerade: r.Masquerade,
NetID: r.NetID,
Enabled: r.Enabled,
Groups: groups,
AccessControlGroups: accessControlGroups,
PeerGroups: peerGroups,
Domains: domains,
KeepRoute: r.KeepRoute,
SkipAutoApply: r.SkipAutoApply,
}
}
func (c *NetworkMapComponents) filterRoutesByGroups(routes []*route.Route, groupListMap LookupMap) []*route.Route { func (c *NetworkMapComponents) filterRoutesByGroups(routes []*route.Route, groupListMap LookupMap) []*route.Route {
var filteredRoutes []*route.Route var filteredRoutes []*route.Route