Merge remote-tracking branch 'origin/main' into proto-ipv6-overlay

# Conflicts:
#	management/server/types/networkmap_components.go
This commit is contained in:
Viktor Liu
2026-04-10 15:21:52 +02:00
7 changed files with 49 additions and 133 deletions

View File

@@ -108,7 +108,7 @@ func (m *managerImpl) CreateResource(ctx context.Context, userID string, resourc
return nil, status.NewPermissionDeniedError()
}
resource, err = types.NewNetworkResource(resource.AccountID, resource.NetworkID, resource.Name, resource.Description, resource.Address, resource.GroupIDs, resource.OnRoutingPeer, resource.Enabled)
resource, err = types.NewNetworkResource(resource.AccountID, resource.NetworkID, resource.Name, resource.Description, resource.Address, resource.GroupIDs, resource.Enabled)
if err != nil {
return nil, fmt.Errorf("failed to create new network resource: %w", err)
}

View File

@@ -29,39 +29,37 @@ func (p NetworkResourceType) String() string {
}
type NetworkResource struct {
ID string `gorm:"primaryKey"`
NetworkID string `gorm:"index"`
AccountID string `gorm:"index"`
Name string
Description string
Type NetworkResourceType
Address string `gorm:"-"`
GroupIDs []string `gorm:"-"`
Domain string
Prefix netip.Prefix `gorm:"serializer:json"`
Enabled bool
OnRoutingPeer bool
ID string `gorm:"primaryKey"`
NetworkID string `gorm:"index"`
AccountID string `gorm:"index"`
Name string
Description string
Type NetworkResourceType
Address string `gorm:"-"`
GroupIDs []string `gorm:"-"`
Domain string
Prefix netip.Prefix `gorm:"serializer:json"`
Enabled bool
}
func NewNetworkResource(accountID, networkID, name, description, address string, groupIDs []string, onRoutingPeer, enabled bool) (*NetworkResource, error) {
func NewNetworkResource(accountID, networkID, name, description, address string, groupIDs []string, enabled bool) (*NetworkResource, error) {
resourceType, domain, prefix, err := GetResourceType(address)
if err != nil {
return nil, fmt.Errorf("invalid address: %w", err)
}
return &NetworkResource{
ID: xid.New().String(),
AccountID: accountID,
NetworkID: networkID,
Name: name,
Description: description,
Type: resourceType,
Address: address,
Domain: domain,
Prefix: prefix,
GroupIDs: groupIDs,
Enabled: enabled,
OnRoutingPeer: onRoutingPeer,
ID: xid.New().String(),
AccountID: accountID,
NetworkID: networkID,
Name: name,
Description: description,
Type: resourceType,
Address: address,
Domain: domain,
Prefix: prefix,
GroupIDs: groupIDs,
Enabled: enabled,
}, nil
}
@@ -72,14 +70,13 @@ func (n *NetworkResource) ToAPIResponse(groups []api.GroupMinimum) *api.NetworkR
}
return &api.NetworkResource{
Id: n.ID,
Name: n.Name,
Description: &n.Description,
Type: api.NetworkResourceType(n.Type.String()),
Address: addr,
Groups: groups,
Enabled: n.Enabled,
OnRoutingPeer: &n.OnRoutingPeer,
Id: n.ID,
Name: n.Name,
Description: &n.Description,
Type: api.NetworkResourceType(n.Type.String()),
Address: addr,
Groups: groups,
Enabled: n.Enabled,
}
}
@@ -89,9 +86,6 @@ func (n *NetworkResource) FromAPIRequest(req *api.NetworkResourceRequest) {
if req.Description != nil {
n.Description = *req.Description
}
if req.OnRoutingPeer != nil {
n.OnRoutingPeer = *req.OnRoutingPeer
}
n.Address = req.Address
n.GroupIDs = req.Groups
n.Enabled = req.Enabled
@@ -99,18 +93,17 @@ func (n *NetworkResource) FromAPIRequest(req *api.NetworkResourceRequest) {
func (n *NetworkResource) Copy() *NetworkResource {
return &NetworkResource{
ID: n.ID,
AccountID: n.AccountID,
NetworkID: n.NetworkID,
Name: n.Name,
Description: n.Description,
Type: n.Type,
Address: n.Address,
Domain: n.Domain,
Prefix: n.Prefix,
GroupIDs: n.GroupIDs,
Enabled: n.Enabled,
OnRoutingPeer: n.OnRoutingPeer,
ID: n.ID,
AccountID: n.AccountID,
NetworkID: n.NetworkID,
Name: n.Name,
Description: n.Description,
Type: n.Type,
Address: n.Address,
Domain: n.Domain,
Prefix: n.Prefix,
GroupIDs: n.GroupIDs,
Enabled: n.Enabled,
}
}

View File

@@ -2307,7 +2307,7 @@ func (s *SqlStore) getNetworkRouters(ctx context.Context, accountID string) ([]*
}
func (s *SqlStore) getNetworkResources(ctx context.Context, accountID string) ([]*resourceTypes.NetworkResource, error) {
const query = `SELECT id, network_id, account_id, name, description, type, domain, prefix, enabled, on_routing_peer FROM network_resources WHERE account_id = $1`
const query = `SELECT id, network_id, account_id, name, description, type, domain, prefix, enabled FROM network_resources WHERE account_id = $1`
rows, err := s.pool.Query(ctx, query, accountID)
if err != nil {
return nil, err
@@ -2316,15 +2316,11 @@ func (s *SqlStore) getNetworkResources(ctx context.Context, accountID string) ([
var r resourceTypes.NetworkResource
var prefix []byte
var enabled sql.NullBool
var onRoutingPeer sql.NullBool
err := row.Scan(&r.ID, &r.NetworkID, &r.AccountID, &r.Name, &r.Description, &r.Type, &r.Domain, &prefix, &enabled, &onRoutingPeer)
err := row.Scan(&r.ID, &r.NetworkID, &r.AccountID, &r.Name, &r.Description, &r.Type, &r.Domain, &prefix, &enabled)
if err == nil {
if enabled.Valid {
r.Enabled = enabled.Bool
}
if onRoutingPeer.Valid {
r.OnRoutingPeer = onRoutingPeer.Bool
}
if prefix != nil {
_ = json.Unmarshal(prefix, &r.Prefix)
}

View File

@@ -2524,7 +2524,7 @@ func TestSqlStore_SaveNetworkResource(t *testing.T) {
accountID := "bf1c8084-ba50-4ce7-9439-34653001fc3b"
networkID := "ct286bi7qv930dsrrug0"
netResource, err := resourceTypes.NewNetworkResource(accountID, networkID, "resource-name", "", "example.com", []string{}, false, true)
netResource, err := resourceTypes.NewNetworkResource(accountID, networkID, "resource-name", "", "example.com", []string{}, true)
require.NoError(t, err)
err = store.SaveNetworkResource(context.Background(), netResource)

View File

@@ -122,10 +122,9 @@ func (c *NetworkMapComponents) Calculate(ctx context.Context) *NetworkMap {
routesUpdate := filterAndExpandRoutes(c.getRoutesToSync(targetPeerID, peersToConnect, peerGroups), includeIPv6)
routesFirewallRules := c.getPeerRoutesFirewallRules(ctx, targetPeerID, includeIPv6)
isRouter, networkResourcesRoutes, sourcePeers, peerFirewallRules := c.getNetworkResourcesRoutesToSync(targetPeerID)
isRouter, networkResourcesRoutes, sourcePeers := c.getNetworkResourcesRoutesToSync(targetPeerID)
var networkResourcesFirewallRules []*RouteFirewallRule
if isRouter {
firewallRules = append(firewallRules, peerFirewallRules...)
networkResourcesFirewallRules = c.getPeerNetworkResourceFirewallRules(ctx, targetPeerID, networkResourcesRoutes, includeIPv6)
}
@@ -560,6 +559,7 @@ func (c *NetworkMapComponents) getRoutingPeerRoutes(peerID string) (enabledRoute
return enabledRoutes, disabledRoutes
}
func (c *NetworkMapComponents) filterRoutesByGroups(routes []*route.Route, groupListMap LookupMap) []*route.Route {
var filteredRoutes []*route.Route
for _, r := range routes {
@@ -727,11 +727,10 @@ func (c *NetworkMapComponents) getRulePeers(rule *PolicyRule, postureChecks []st
return distributionGroupPeers
}
func (c *NetworkMapComponents) getNetworkResourcesRoutesToSync(peerID string) (bool, []*route.Route, map[string]struct{}, []*FirewallRule) {
func (c *NetworkMapComponents) getNetworkResourcesRoutesToSync(peerID string) (bool, []*route.Route, map[string]struct{}) {
var isRoutingPeer bool
var routes []*route.Route
allSourcePeers := make(map[string]struct{})
localResourceFwRule := make([]*FirewallRule, 0)
for _, resource := range c.NetworkResources {
if !resource.Enabled {
@@ -750,9 +749,6 @@ func (c *NetworkMapComponents) getNetworkResourcesRoutesToSync(peerID string) (b
addedResourceRoute := false
for _, policy := range c.ResourcePoliciesMap[resource.ID] {
if isRoutingPeer && resource.OnRoutingPeer {
localResourceFwRule = append(localResourceFwRule, c.getLocalResourceFirewallRules(policy)...)
}
var peers []string
if policy.Rules[0].SourceResource.Type == ResourceTypePeer && policy.Rules[0].SourceResource.ID != "" {
peers = []string{policy.Rules[0].SourceResource.ID}
@@ -775,63 +771,7 @@ func (c *NetworkMapComponents) getNetworkResourcesRoutesToSync(peerID string) (b
}
}
return isRoutingPeer, routes, allSourcePeers, localResourceFwRule
}
func (c *NetworkMapComponents) getLocalResourceFirewallRules(policy *Policy) []*FirewallRule {
sourcePeerIDs := c.getPoliciesSourcePeers([]*Policy{policy})
postureValidatedPeerIDs := c.getPostureValidPeers(slices.Collect(maps.Keys(sourcePeerIDs)), policy.SourcePostureChecks)
rules := make([]*FirewallRule, 0)
for _, rule := range policy.Rules {
if !rule.Enabled {
continue
}
protocol := rule.Protocol
if protocol == PolicyRuleProtocolNetbirdSSH {
continue
}
for _, peerID := range postureValidatedPeerIDs {
peer := c.GetPeerInfo(peerID)
if peer == nil {
continue
}
peerIP := peer.IP.String()
fr := FirewallRule{
PolicyID: rule.ID,
PeerIP: peerIP,
Direction: FirewallRuleDirectionIN,
Action: string(rule.Action),
Protocol: string(protocol),
}
if len(rule.Ports) == 0 && len(rule.PortRanges) == 0 {
rules = append(rules, &fr)
continue
}
for _, port := range rule.Ports {
portRule := fr
portRule.Port = port
rules = append(rules, &portRule)
}
for _, portRange := range rule.PortRanges {
if len(rule.Ports) > 0 {
break
}
rangeRule := fr
rangeRule.PortRange = portRange
rules = append(rules, &rangeRule)
}
}
}
return rules
return isRoutingPeer, routes, allSourcePeers
}
func (c *NetworkMapComponents) getNetworkResourcesRoutes(resource *resourceTypes.NetworkResource, peerID string, router *routerTypes.NetworkRouter) []*route.Route {

View File

@@ -2004,10 +2004,6 @@ components:
description: Network resource status
type: boolean
example: true
on_routing_peer:
description: Indicate if the resource is on a routing peer or not. It is needed if the resource is targeting the IP of the routing peer itself
type: boolean
example: true
required:
- name
- address

View File

@@ -2737,9 +2737,6 @@ type NetworkResource struct {
// Name Network resource name
Name string `json:"name"`
// OnRoutingPeer Indicate if the resource is on a routing peer or not. It is needed if the resource is targeting the IP of the routing peer itself
OnRoutingPeer *bool `json:"on_routing_peer,omitempty"`
// Type Network resource type based of the address
Type NetworkResourceType `json:"type"`
}
@@ -2757,9 +2754,6 @@ type NetworkResourceMinimum struct {
// Name Network resource name
Name string `json:"name"`
// OnRoutingPeer Indicate if the resource is on a routing peer or not. It is needed if the resource is targeting the IP of the routing peer itself
OnRoutingPeer *bool `json:"on_routing_peer,omitempty"`
}
// NetworkResourceRequest defines model for NetworkResourceRequest.
@@ -2778,9 +2772,6 @@ type NetworkResourceRequest struct {
// Name Network resource name
Name string `json:"name"`
// OnRoutingPeer Indicate if the resource is on a routing peer or not. It is needed if the resource is targeting the IP of the routing peer itself
OnRoutingPeer *bool `json:"on_routing_peer,omitempty"`
}
// NetworkResourceType Network resource type based of the address