mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-15 23:06:38 +00:00
This commit is contained in:
@@ -108,7 +108,7 @@ func (m *managerImpl) CreateResource(ctx context.Context, userID string, resourc
|
|||||||
return nil, status.NewPermissionDeniedError()
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create new network resource: %w", err)
|
return nil, fmt.Errorf("failed to create new network resource: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,39 +29,37 @@ func (p NetworkResourceType) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type NetworkResource struct {
|
type NetworkResource struct {
|
||||||
ID string `gorm:"primaryKey"`
|
ID string `gorm:"primaryKey"`
|
||||||
NetworkID string `gorm:"index"`
|
NetworkID string `gorm:"index"`
|
||||||
AccountID string `gorm:"index"`
|
AccountID string `gorm:"index"`
|
||||||
Name string
|
Name string
|
||||||
Description string
|
Description string
|
||||||
Type NetworkResourceType
|
Type NetworkResourceType
|
||||||
Address string `gorm:"-"`
|
Address string `gorm:"-"`
|
||||||
GroupIDs []string `gorm:"-"`
|
GroupIDs []string `gorm:"-"`
|
||||||
Domain string
|
Domain string
|
||||||
Prefix netip.Prefix `gorm:"serializer:json"`
|
Prefix netip.Prefix `gorm:"serializer:json"`
|
||||||
Enabled bool
|
Enabled bool
|
||||||
OnRoutingPeer 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)
|
resourceType, domain, prefix, err := GetResourceType(address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid address: %w", err)
|
return nil, fmt.Errorf("invalid address: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &NetworkResource{
|
return &NetworkResource{
|
||||||
ID: xid.New().String(),
|
ID: xid.New().String(),
|
||||||
AccountID: accountID,
|
AccountID: accountID,
|
||||||
NetworkID: networkID,
|
NetworkID: networkID,
|
||||||
Name: name,
|
Name: name,
|
||||||
Description: description,
|
Description: description,
|
||||||
Type: resourceType,
|
Type: resourceType,
|
||||||
Address: address,
|
Address: address,
|
||||||
Domain: domain,
|
Domain: domain,
|
||||||
Prefix: prefix,
|
Prefix: prefix,
|
||||||
GroupIDs: groupIDs,
|
GroupIDs: groupIDs,
|
||||||
Enabled: enabled,
|
Enabled: enabled,
|
||||||
OnRoutingPeer: onRoutingPeer,
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,14 +70,13 @@ func (n *NetworkResource) ToAPIResponse(groups []api.GroupMinimum) *api.NetworkR
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &api.NetworkResource{
|
return &api.NetworkResource{
|
||||||
Id: n.ID,
|
Id: n.ID,
|
||||||
Name: n.Name,
|
Name: n.Name,
|
||||||
Description: &n.Description,
|
Description: &n.Description,
|
||||||
Type: api.NetworkResourceType(n.Type.String()),
|
Type: api.NetworkResourceType(n.Type.String()),
|
||||||
Address: addr,
|
Address: addr,
|
||||||
Groups: groups,
|
Groups: groups,
|
||||||
Enabled: n.Enabled,
|
Enabled: n.Enabled,
|
||||||
OnRoutingPeer: &n.OnRoutingPeer,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,9 +86,6 @@ func (n *NetworkResource) FromAPIRequest(req *api.NetworkResourceRequest) {
|
|||||||
if req.Description != nil {
|
if req.Description != nil {
|
||||||
n.Description = *req.Description
|
n.Description = *req.Description
|
||||||
}
|
}
|
||||||
if req.OnRoutingPeer != nil {
|
|
||||||
n.OnRoutingPeer = *req.OnRoutingPeer
|
|
||||||
}
|
|
||||||
n.Address = req.Address
|
n.Address = req.Address
|
||||||
n.GroupIDs = req.Groups
|
n.GroupIDs = req.Groups
|
||||||
n.Enabled = req.Enabled
|
n.Enabled = req.Enabled
|
||||||
@@ -99,18 +93,17 @@ func (n *NetworkResource) FromAPIRequest(req *api.NetworkResourceRequest) {
|
|||||||
|
|
||||||
func (n *NetworkResource) Copy() *NetworkResource {
|
func (n *NetworkResource) Copy() *NetworkResource {
|
||||||
return &NetworkResource{
|
return &NetworkResource{
|
||||||
ID: n.ID,
|
ID: n.ID,
|
||||||
AccountID: n.AccountID,
|
AccountID: n.AccountID,
|
||||||
NetworkID: n.NetworkID,
|
NetworkID: n.NetworkID,
|
||||||
Name: n.Name,
|
Name: n.Name,
|
||||||
Description: n.Description,
|
Description: n.Description,
|
||||||
Type: n.Type,
|
Type: n.Type,
|
||||||
Address: n.Address,
|
Address: n.Address,
|
||||||
Domain: n.Domain,
|
Domain: n.Domain,
|
||||||
Prefix: n.Prefix,
|
Prefix: n.Prefix,
|
||||||
GroupIDs: n.GroupIDs,
|
GroupIDs: n.GroupIDs,
|
||||||
Enabled: n.Enabled,
|
Enabled: n.Enabled,
|
||||||
OnRoutingPeer: n.OnRoutingPeer,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2291,7 +2291,7 @@ func (s *SqlStore) getNetworkRouters(ctx context.Context, accountID string) ([]*
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *SqlStore) getNetworkResources(ctx context.Context, accountID string) ([]*resourceTypes.NetworkResource, error) {
|
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)
|
rows, err := s.pool.Query(ctx, query, accountID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -2300,15 +2300,11 @@ func (s *SqlStore) getNetworkResources(ctx context.Context, accountID string) ([
|
|||||||
var r resourceTypes.NetworkResource
|
var r resourceTypes.NetworkResource
|
||||||
var prefix []byte
|
var prefix []byte
|
||||||
var enabled sql.NullBool
|
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)
|
||||||
err := row.Scan(&r.ID, &r.NetworkID, &r.AccountID, &r.Name, &r.Description, &r.Type, &r.Domain, &prefix, &enabled, &onRoutingPeer)
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if enabled.Valid {
|
if enabled.Valid {
|
||||||
r.Enabled = enabled.Bool
|
r.Enabled = enabled.Bool
|
||||||
}
|
}
|
||||||
if onRoutingPeer.Valid {
|
|
||||||
r.OnRoutingPeer = onRoutingPeer.Bool
|
|
||||||
}
|
|
||||||
if prefix != nil {
|
if prefix != nil {
|
||||||
_ = json.Unmarshal(prefix, &r.Prefix)
|
_ = json.Unmarshal(prefix, &r.Prefix)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2508,7 +2508,7 @@ func TestSqlStore_SaveNetworkResource(t *testing.T) {
|
|||||||
accountID := "bf1c8084-ba50-4ce7-9439-34653001fc3b"
|
accountID := "bf1c8084-ba50-4ce7-9439-34653001fc3b"
|
||||||
networkID := "ct286bi7qv930dsrrug0"
|
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)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = store.SaveNetworkResource(context.Background(), netResource)
|
err = store.SaveNetworkResource(context.Background(), netResource)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package types
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"maps"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"slices"
|
"slices"
|
||||||
@@ -16,7 +17,6 @@ import (
|
|||||||
nbpeer "github.com/netbirdio/netbird/management/server/peer"
|
nbpeer "github.com/netbirdio/netbird/management/server/peer"
|
||||||
"github.com/netbirdio/netbird/route"
|
"github.com/netbirdio/netbird/route"
|
||||||
"github.com/netbirdio/netbird/shared/management/domain"
|
"github.com/netbirdio/netbird/shared/management/domain"
|
||||||
"golang.org/x/exp/maps"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const EnvNewNetworkMapCompacted = "NB_NETWORK_MAP_COMPACTED"
|
const EnvNewNetworkMapCompacted = "NB_NETWORK_MAP_COMPACTED"
|
||||||
@@ -119,10 +119,9 @@ func (c *NetworkMapComponents) Calculate(ctx context.Context) *NetworkMap {
|
|||||||
routesUpdate := c.getRoutesToSync(targetPeerID, peersToConnect, peerGroups)
|
routesUpdate := c.getRoutesToSync(targetPeerID, peersToConnect, peerGroups)
|
||||||
routesFirewallRules := c.getPeerRoutesFirewallRules(ctx, targetPeerID)
|
routesFirewallRules := c.getPeerRoutesFirewallRules(ctx, targetPeerID)
|
||||||
|
|
||||||
isRouter, networkResourcesRoutes, sourcePeers, peerFirewallRules := c.getNetworkResourcesRoutesToSync(targetPeerID)
|
isRouter, networkResourcesRoutes, sourcePeers := c.getNetworkResourcesRoutesToSync(targetPeerID)
|
||||||
var networkResourcesFirewallRules []*RouteFirewallRule
|
var networkResourcesFirewallRules []*RouteFirewallRule
|
||||||
if isRouter {
|
if isRouter {
|
||||||
firewallRules = append(firewallRules, peerFirewallRules...)
|
|
||||||
networkResourcesFirewallRules = c.getPeerNetworkResourceFirewallRules(ctx, targetPeerID, networkResourcesRoutes)
|
networkResourcesFirewallRules = c.getPeerNetworkResourceFirewallRules(ctx, targetPeerID, networkResourcesRoutes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,6 +526,7 @@ func (c *NetworkMapComponents) getRoutingPeerRoutes(peerID string) (enabledRoute
|
|||||||
return enabledRoutes, disabledRoutes
|
return enabledRoutes, disabledRoutes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
for _, r := range routes {
|
for _, r := range routes {
|
||||||
@@ -692,11 +692,10 @@ func (c *NetworkMapComponents) getRulePeers(rule *PolicyRule, postureChecks []st
|
|||||||
return distributionGroupPeers
|
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 isRoutingPeer bool
|
||||||
var routes []*route.Route
|
var routes []*route.Route
|
||||||
allSourcePeers := make(map[string]struct{})
|
allSourcePeers := make(map[string]struct{})
|
||||||
localResourceFwRule := make([]*FirewallRule, 0)
|
|
||||||
|
|
||||||
for _, resource := range c.NetworkResources {
|
for _, resource := range c.NetworkResources {
|
||||||
if !resource.Enabled {
|
if !resource.Enabled {
|
||||||
@@ -715,9 +714,6 @@ func (c *NetworkMapComponents) getNetworkResourcesRoutesToSync(peerID string) (b
|
|||||||
|
|
||||||
addedResourceRoute := false
|
addedResourceRoute := false
|
||||||
for _, policy := range c.ResourcePoliciesMap[resource.ID] {
|
for _, policy := range c.ResourcePoliciesMap[resource.ID] {
|
||||||
if isRoutingPeer && resource.OnRoutingPeer {
|
|
||||||
localResourceFwRule = append(localResourceFwRule, c.getLocalResourceFirewallRules(policy)...)
|
|
||||||
}
|
|
||||||
var peers []string
|
var peers []string
|
||||||
if policy.Rules[0].SourceResource.Type == ResourceTypePeer && policy.Rules[0].SourceResource.ID != "" {
|
if policy.Rules[0].SourceResource.Type == ResourceTypePeer && policy.Rules[0].SourceResource.ID != "" {
|
||||||
peers = []string{policy.Rules[0].SourceResource.ID}
|
peers = []string{policy.Rules[0].SourceResource.ID}
|
||||||
@@ -740,63 +736,7 @@ func (c *NetworkMapComponents) getNetworkResourcesRoutesToSync(peerID string) (b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return isRoutingPeer, routes, allSourcePeers, localResourceFwRule
|
return isRoutingPeer, routes, allSourcePeers
|
||||||
}
|
|
||||||
|
|
||||||
func (c *NetworkMapComponents) getLocalResourceFirewallRules(policy *Policy) []*FirewallRule {
|
|
||||||
sourcePeerIDs := c.getPoliciesSourcePeers([]*Policy{policy})
|
|
||||||
postureValidatedPeerIDs := c.getPostureValidPeers(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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *NetworkMapComponents) getNetworkResourcesRoutes(resource *resourceTypes.NetworkResource, peerID string, router *routerTypes.NetworkRouter) []*route.Route {
|
func (c *NetworkMapComponents) getNetworkResourcesRoutes(resource *resourceTypes.NetworkResource, peerID string, router *routerTypes.NetworkRouter) []*route.Route {
|
||||||
|
|||||||
@@ -1980,10 +1980,6 @@ components:
|
|||||||
description: Network resource status
|
description: Network resource status
|
||||||
type: boolean
|
type: boolean
|
||||||
example: true
|
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:
|
required:
|
||||||
- name
|
- name
|
||||||
- address
|
- address
|
||||||
|
|||||||
@@ -2728,9 +2728,6 @@ type NetworkResource struct {
|
|||||||
// Name Network resource name
|
// Name Network resource name
|
||||||
Name string `json:"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 Network resource type based of the address
|
||||||
Type NetworkResourceType `json:"type"`
|
Type NetworkResourceType `json:"type"`
|
||||||
}
|
}
|
||||||
@@ -2748,9 +2745,6 @@ type NetworkResourceMinimum struct {
|
|||||||
|
|
||||||
// Name Network resource name
|
// Name Network resource name
|
||||||
Name string `json:"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.
|
// NetworkResourceRequest defines model for NetworkResourceRequest.
|
||||||
@@ -2769,9 +2763,6 @@ type NetworkResourceRequest struct {
|
|||||||
|
|
||||||
// Name Network resource name
|
// Name Network resource name
|
||||||
Name string `json:"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
|
// NetworkResourceType Network resource type based of the address
|
||||||
|
|||||||
Reference in New Issue
Block a user