diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 447164a9b62..4697acf203e 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.21-bullseye +FROM golang:1.23-bullseye RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ && apt-get -y install --no-install-recommends\ diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ef883d31af5..97aad75ad3b 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -7,7 +7,7 @@ "features": { "ghcr.io/devcontainers/features/docker-in-docker:2": {}, "ghcr.io/devcontainers/features/go:1": { - "version": "1.21" + "version": "1.23" } }, "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", diff --git a/management/server/http/api/openapi.yml b/management/server/http/api/openapi.yml index 6c1d6b424a5..f53092415bf 100644 --- a/management/server/http/api/openapi.yml +++ b/management/server/http/api/openapi.yml @@ -800,15 +800,18 @@ components: items: type: string example: "ch8i4ug6lnn4g9hqv797" + sourceResource: + description: Policy rule source resource that the rule is applied to + $ref: '#/components/schemas/Resource' destinations: description: Policy rule destination group IDs type: array items: type: string example: "ch8i4ug6lnn4g9h7v7m0" - required: - - sources - - destinations + destinationResource: + description: Policy rule destination resource that the rule is applied to + $ref: '#/components/schemas/Resource' PolicyRuleCreate: allOf: @@ -1325,9 +1328,14 @@ components: description: Network resource address (either a direct host like 1.1.1.1 or 1.1.1.1/32, or a subnet like 192.168.178.0/24, or domains like example.com and *.example.com) type: string example: "1.1.1.1" + enabled: + description: Network resource status + type: boolean + example: true required: - name - address + - enabled NetworkResourceRequest: allOf: - $ref: '#/components/schemas/NetworkResourceMinimum' @@ -1390,12 +1398,17 @@ components: description: Indicate if peer should masquerade traffic to this route's prefix type: boolean example: true + enabled: + description: Network router status + type: boolean + example: true required: # Only one property has to be set #- peer #- peer_groups - metric - masquerade + - enabled NetworkRouter: allOf: - type: object diff --git a/management/server/http/api/types.gen.go b/management/server/http/api/types.gen.go index 83226587fb9..943d1b3277a 100644 --- a/management/server/http/api/types.gen.go +++ b/management/server/http/api/types.gen.go @@ -560,6 +560,9 @@ type NetworkResource struct { // Description Network resource description Description *string `json:"description,omitempty"` + // Enabled Network resource status + Enabled bool `json:"enabled"` + // Groups Groups that the resource belongs to Groups []GroupMinimum `json:"groups"` @@ -581,6 +584,9 @@ type NetworkResourceMinimum struct { // Description Network resource description Description *string `json:"description,omitempty"` + // Enabled Network resource status + Enabled bool `json:"enabled"` + // Name Network resource name Name string `json:"name"` } @@ -593,6 +599,9 @@ type NetworkResourceRequest struct { // Description Network resource description Description *string `json:"description,omitempty"` + // Enabled Network resource status + Enabled bool `json:"enabled"` + // Groups Group IDs containing the resource Groups []string `json:"groups"` @@ -605,6 +614,9 @@ type NetworkResourceType string // NetworkRouter defines model for NetworkRouter. type NetworkRouter struct { + // Enabled Network router status + Enabled bool `json:"enabled"` + // Id Network Router Id Id string `json:"id"` @@ -623,6 +635,9 @@ type NetworkRouter struct { // NetworkRouterRequest defines model for NetworkRouterRequest. type NetworkRouterRequest struct { + // Enabled Network router status + Enabled bool `json:"enabled"` + // Masquerade Indicate if peer should masquerade traffic to this route's prefix Masquerade bool `json:"masquerade"` diff --git a/management/server/migration/migration.go b/management/server/migration/migration.go index 0a6951736a6..8986d77b505 100644 --- a/management/server/migration/migration.go +++ b/management/server/migration/migration.go @@ -305,3 +305,53 @@ func hiddenKey(key string, length int) string { } return prefix + strings.Repeat("*", length) } + +func MigrateNewField[T any](ctx context.Context, db *gorm.DB, columnName string, defaultValue any) error { + var model T + + if !db.Migrator().HasTable(&model) { + log.WithContext(ctx).Debugf("Table for %T does not exist, no migration needed", model) + return nil + } + + stmt := &gorm.Statement{DB: db} + err := stmt.Parse(&model) + if err != nil { + return fmt.Errorf("parse model: %w", err) + } + tableName := stmt.Schema.Table + + if err := db.Transaction(func(tx *gorm.DB) error { + if !tx.Migrator().HasColumn(&model, columnName) { + log.WithContext(ctx).Infof("Column %s does not exist in table %s, adding it", columnName, tableName) + if err := tx.Migrator().AddColumn(&model, columnName); err != nil { + return fmt.Errorf("add column %s: %w", columnName, err) + } + } + + var rows []map[string]any + if err := tx.Table(tableName). + Select("id", columnName). + Where(columnName + " IS NULL OR " + columnName + " = ''"). + Find(&rows).Error; err != nil { + return fmt.Errorf("failed to find rows with empty %s: %w", columnName, err) + } + + if len(rows) == 0 { + log.WithContext(ctx).Infof("No rows with empty %s found in table %s, no migration needed", columnName, tableName) + return nil + } + + for _, row := range rows { + if err := tx.Table(tableName).Where("id = ?", row["id"]).Update(columnName, defaultValue).Error; err != nil { + return fmt.Errorf("failed to update row with id %v: %w", row["id"], err) + } + } + return nil + }); err != nil { + return err + } + + log.WithContext(ctx).Infof("Migration of empty %s to default value in table %s completed", columnName, tableName) + return nil +} diff --git a/management/server/networks/resources/manager.go b/management/server/networks/resources/manager.go index 02b46294785..725d1549663 100644 --- a/management/server/networks/resources/manager.go +++ b/management/server/networks/resources/manager.go @@ -101,7 +101,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, 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) } diff --git a/management/server/networks/resources/types/resource.go b/management/server/networks/resources/types/resource.go index 162f9037891..0df6727c36a 100644 --- a/management/server/networks/resources/types/resource.go +++ b/management/server/networks/resources/types/resource.go @@ -40,9 +40,10 @@ type NetworkResource struct { GroupIDs []string `gorm:"-"` Domain string Prefix netip.Prefix `gorm:"serializer:json"` + Enabled bool } -func NewNetworkResource(accountID, networkID, name, description, address string, groupIDs []string) (*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) @@ -59,6 +60,7 @@ func NewNetworkResource(accountID, networkID, name, description, address string, Domain: domain, Prefix: prefix, GroupIDs: groupIDs, + Enabled: enabled, }, nil } @@ -75,6 +77,7 @@ func (n *NetworkResource) ToAPIResponse(groups []api.GroupMinimum) *api.NetworkR Type: api.NetworkResourceType(n.Type.String()), Address: addr, Groups: groups, + Enabled: n.Enabled, } } @@ -86,6 +89,7 @@ func (n *NetworkResource) FromAPIRequest(req *api.NetworkResourceRequest) { } n.Address = req.Address n.GroupIDs = req.Groups + n.Enabled = req.Enabled } func (n *NetworkResource) Copy() *NetworkResource { @@ -100,6 +104,7 @@ func (n *NetworkResource) Copy() *NetworkResource { Domain: n.Domain, Prefix: n.Prefix, GroupIDs: n.GroupIDs, + Enabled: n.Enabled, } } @@ -115,7 +120,7 @@ func (n *NetworkResource) ToRoute(peer *nbpeer.Peer, router *routerTypes.Network PeerGroups: nil, Masquerade: router.Masquerade, Metric: router.Metric, - Enabled: true, + Enabled: n.Enabled, Groups: nil, AccessControlGroups: nil, } diff --git a/management/server/networks/routers/manager_test.go b/management/server/networks/routers/manager_test.go index e650074cc17..47f5ad7e308 100644 --- a/management/server/networks/routers/manager_test.go +++ b/management/server/networks/routers/manager_test.go @@ -101,7 +101,7 @@ func Test_GetRouterReturnsPermissionDenied(t *testing.T) { func Test_CreateRouterSuccessfully(t *testing.T) { ctx := context.Background() userID := "allowedUser" - router, err := types.NewNetworkRouter("testAccountId", "testNetworkId", "testPeerId", []string{}, false, 9999) + router, err := types.NewNetworkRouter("testAccountId", "testNetworkId", "testPeerId", []string{}, false, 9999, true) if err != nil { require.NoError(t, err) } @@ -127,7 +127,7 @@ func Test_CreateRouterSuccessfully(t *testing.T) { func Test_CreateRouterFailsWithPermissionDenied(t *testing.T) { ctx := context.Background() userID := "invalidUser" - router, err := types.NewNetworkRouter("testAccountId", "testNetworkId", "testPeerId", []string{}, false, 9999) + router, err := types.NewNetworkRouter("testAccountId", "testNetworkId", "testPeerId", []string{}, false, 9999, true) if err != nil { require.NoError(t, err) } @@ -191,7 +191,7 @@ func Test_DeleteRouterFailsWithPermissionDenied(t *testing.T) { func Test_UpdateRouterSuccessfully(t *testing.T) { ctx := context.Background() userID := "allowedUser" - router, err := types.NewNetworkRouter("testAccountId", "testNetworkId", "testPeerId", []string{}, false, 1) + router, err := types.NewNetworkRouter("testAccountId", "testNetworkId", "testPeerId", []string{}, false, 1, true) if err != nil { require.NoError(t, err) } @@ -213,7 +213,7 @@ func Test_UpdateRouterSuccessfully(t *testing.T) { func Test_UpdateRouterFailsWithPermissionDenied(t *testing.T) { ctx := context.Background() userID := "invalidUser" - router, err := types.NewNetworkRouter("testAccountId", "testNetworkId", "testPeerId", []string{}, false, 1) + router, err := types.NewNetworkRouter("testAccountId", "testNetworkId", "testPeerId", []string{}, false, 1, true) if err != nil { require.NoError(t, err) } diff --git a/management/server/networks/routers/types/router.go b/management/server/networks/routers/types/router.go index f37ae0861a0..5158ebb1204 100644 --- a/management/server/networks/routers/types/router.go +++ b/management/server/networks/routers/types/router.go @@ -17,9 +17,10 @@ type NetworkRouter struct { PeerGroups []string `gorm:"serializer:json"` Masquerade bool Metric int + Enabled bool } -func NewNetworkRouter(accountID string, networkID string, peer string, peerGroups []string, masquerade bool, metric int) (*NetworkRouter, error) { +func NewNetworkRouter(accountID string, networkID string, peer string, peerGroups []string, masquerade bool, metric int, enabled bool) (*NetworkRouter, error) { if peer != "" && len(peerGroups) > 0 { return nil, errors.New("peer and peerGroups cannot be set at the same time") } @@ -32,6 +33,7 @@ func NewNetworkRouter(accountID string, networkID string, peer string, peerGroup PeerGroups: peerGroups, Masquerade: masquerade, Metric: metric, + Enabled: enabled, }, nil } @@ -42,6 +44,7 @@ func (n *NetworkRouter) ToAPIResponse() *api.NetworkRouter { PeerGroups: &n.PeerGroups, Masquerade: n.Masquerade, Metric: n.Metric, + Enabled: n.Enabled, } } @@ -56,6 +59,7 @@ func (n *NetworkRouter) FromAPIRequest(req *api.NetworkRouterRequest) { n.Masquerade = req.Masquerade n.Metric = req.Metric + n.Enabled = req.Enabled } func (n *NetworkRouter) Copy() *NetworkRouter { @@ -67,6 +71,7 @@ func (n *NetworkRouter) Copy() *NetworkRouter { PeerGroups: n.PeerGroups, Masquerade: n.Masquerade, Metric: n.Metric, + Enabled: n.Enabled, } } diff --git a/management/server/networks/routers/types/router_test.go b/management/server/networks/routers/types/router_test.go index 3335f7c895b..5801e3bfa05 100644 --- a/management/server/networks/routers/types/router_test.go +++ b/management/server/networks/routers/types/router_test.go @@ -11,6 +11,7 @@ func TestNewNetworkRouter(t *testing.T) { peerGroups []string masquerade bool metric int + enabled bool expectedError bool }{ // Valid cases @@ -22,6 +23,7 @@ func TestNewNetworkRouter(t *testing.T) { peerGroups: nil, masquerade: true, metric: 100, + enabled: true, expectedError: false, }, { @@ -32,6 +34,7 @@ func TestNewNetworkRouter(t *testing.T) { peerGroups: []string{"group-1", "group-2"}, masquerade: false, metric: 200, + enabled: false, expectedError: false, }, { @@ -42,6 +45,7 @@ func TestNewNetworkRouter(t *testing.T) { peerGroups: nil, masquerade: true, metric: 300, + enabled: true, expectedError: false, }, @@ -54,13 +58,14 @@ func TestNewNetworkRouter(t *testing.T) { peerGroups: []string{"group-3"}, masquerade: false, metric: 400, + enabled: false, expectedError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - router, err := NewNetworkRouter(tt.accountID, tt.networkID, tt.peer, tt.peerGroups, tt.masquerade, tt.metric) + router, err := NewNetworkRouter(tt.accountID, tt.networkID, tt.peer, tt.peerGroups, tt.masquerade, tt.metric, tt.enabled) if tt.expectedError && err == nil { t.Fatalf("Expected an error, got nil") @@ -94,6 +99,10 @@ func TestNewNetworkRouter(t *testing.T) { if router.Metric != tt.metric { t.Errorf("Expected Metric %d, got %d", tt.metric, router.Metric) } + + if router.Enabled != tt.enabled { + t.Errorf("Expected Enabled %v, got %v", tt.enabled, router.Enabled) + } } }) } diff --git a/management/server/peer_test.go b/management/server/peer_test.go index 5f500c2267c..0c751e6c409 100644 --- a/management/server/peer_test.go +++ b/management/server/peer_test.go @@ -13,13 +13,14 @@ import ( "testing" "time" - "github.com/netbirdio/netbird/management/server/util" "github.com/rs/xid" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" + "github.com/netbirdio/netbird/management/server/util" + resourceTypes "github.com/netbirdio/netbird/management/server/networks/resources/types" routerTypes "github.com/netbirdio/netbird/management/server/networks/routers/types" networkTypes "github.com/netbirdio/netbird/management/server/networks/types" @@ -937,7 +938,7 @@ func BenchmarkUpdateAccountPeers(b *testing.B) { {"Small single", 50, 10, 90, 120, 90, 120}, {"Medium single", 500, 10, 110, 170, 120, 200}, {"Large 5", 5000, 15, 1300, 2100, 4900, 7000}, - {"Extra Large", 2000, 2000, 1300, 2400, 4000, 6400}, + {"Extra Large", 2000, 2000, 1300, 2400, 3900, 6400}, } log.SetOutput(io.Discard) diff --git a/management/server/route_test.go b/management/server/route_test.go index 48dbd11ed4a..1c5c56f6069 100644 --- a/management/server/route_test.go +++ b/management/server/route_test.go @@ -2388,6 +2388,7 @@ func TestAccount_GetPeerNetworkResourceFirewallRules(t *testing.T) { PeerGroups: nil, Masquerade: false, Metric: 9999, + Enabled: true, }, { ID: "router2", @@ -2395,12 +2396,14 @@ func TestAccount_GetPeerNetworkResourceFirewallRules(t *testing.T) { PeerGroups: []string{"router1", "router2"}, Masquerade: false, Metric: 9999, + Enabled: true, }, { ID: "router3", NetworkID: "network3", Peer: "peerE", PeerGroups: []string{}, + Enabled: true, }, { ID: "router4", @@ -2408,6 +2411,7 @@ func TestAccount_GetPeerNetworkResourceFirewallRules(t *testing.T) { PeerGroups: []string{"router1"}, Masquerade: false, Metric: 9999, + Enabled: true, }, { ID: "router5", @@ -2415,6 +2419,7 @@ func TestAccount_GetPeerNetworkResourceFirewallRules(t *testing.T) { Peer: "peerL", Masquerade: false, Metric: 9999, + Enabled: true, }, { ID: "router6", @@ -2422,6 +2427,7 @@ func TestAccount_GetPeerNetworkResourceFirewallRules(t *testing.T) { Peer: "peerN", Masquerade: false, Metric: 9999, + Enabled: true, }, }, NetworkResources: []*resourceTypes.NetworkResource{ @@ -2431,6 +2437,7 @@ func TestAccount_GetPeerNetworkResourceFirewallRules(t *testing.T) { Name: "Resource 1", Type: "subnet", Prefix: netip.MustParsePrefix("10.10.10.0/24"), + Enabled: true, }, { ID: "resource2", @@ -2438,6 +2445,7 @@ func TestAccount_GetPeerNetworkResourceFirewallRules(t *testing.T) { Name: "Resource 2", Type: "subnet", Prefix: netip.MustParsePrefix("192.168.0.0/16"), + Enabled: true, }, { ID: "resource3", @@ -2445,6 +2453,7 @@ func TestAccount_GetPeerNetworkResourceFirewallRules(t *testing.T) { Name: "Resource 3", Type: "domain", Domain: "example.com", + Enabled: true, }, { ID: "resource4", @@ -2452,6 +2461,7 @@ func TestAccount_GetPeerNetworkResourceFirewallRules(t *testing.T) { Name: "Resource 4", Type: "domain", Domain: "example.com", + Enabled: true, }, { ID: "resource5", @@ -2459,6 +2469,7 @@ func TestAccount_GetPeerNetworkResourceFirewallRules(t *testing.T) { Name: "Resource 5", Type: "host", Prefix: netip.MustParsePrefix("10.12.12.1/32"), + Enabled: true, }, { ID: "resource6", @@ -2466,6 +2477,7 @@ func TestAccount_GetPeerNetworkResourceFirewallRules(t *testing.T) { Name: "Resource 6", Type: "domain", Domain: "*.google.com", + Enabled: true, }, }, Policies: []*types.Policy{ diff --git a/management/server/store/sql_store_test.go b/management/server/store/sql_store_test.go index 845bc8fd474..5928b45baa7 100644 --- a/management/server/store/sql_store_test.go +++ b/management/server/store/sql_store_test.go @@ -2377,7 +2377,7 @@ func TestSqlStore_SaveNetworkRouter(t *testing.T) { accountID := "bf1c8084-ba50-4ce7-9439-34653001fc3b" networkID := "ct286bi7qv930dsrrug0" - netRouter, err := routerTypes.NewNetworkRouter(accountID, networkID, "", []string{"net-router-grp"}, true, 0) + netRouter, err := routerTypes.NewNetworkRouter(accountID, networkID, "", []string{"net-router-grp"}, true, 0, true) require.NoError(t, err) err = store.SaveNetworkRouter(context.Background(), LockingStrengthUpdate, netRouter) @@ -2494,7 +2494,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{}) + netResource, err := resourceTypes.NewNetworkResource(accountID, networkID, "resource-name", "", "example.com", []string{}, true) require.NoError(t, err) err = store.SaveNetworkResource(context.Background(), LockingStrengthUpdate, netResource) diff --git a/management/server/store/store.go b/management/server/store/store.go index e1a6937e712..91ae93c7c34 100644 --- a/management/server/store/store.go +++ b/management/server/store/store.go @@ -288,6 +288,12 @@ func getMigrations(ctx context.Context) []migrationFunc { func(db *gorm.DB) error { return migration.MigrateSetupKeyToHashedSetupKey[types.SetupKey](ctx, db) }, + func(db *gorm.DB) error { + return migration.MigrateNewField[resourceTypes.NetworkResource](ctx, db, "enabled", true) + }, + func(db *gorm.DB) error { + return migration.MigrateNewField[routerTypes.NetworkRouter](ctx, db, "enabled", true) + }, } } diff --git a/management/server/token_mgr.go b/management/server/token_mgr.go index ef8276b5924..fd67fa3e328 100644 --- a/management/server/token_mgr.go +++ b/management/server/token_mgr.go @@ -158,7 +158,7 @@ func (m *TimeBasedAuthSecretsManager) refreshTURNTokens(ctx context.Context, pee log.WithContext(ctx).Debugf("stopping TURN refresh for %s", peerID) return case <-ticker.C: - m.pushNewTURNTokens(ctx, peerID) + m.pushNewTURNAndRelayTokens(ctx, peerID) } } } @@ -178,7 +178,7 @@ func (m *TimeBasedAuthSecretsManager) refreshRelayTokens(ctx context.Context, pe } } -func (m *TimeBasedAuthSecretsManager) pushNewTURNTokens(ctx context.Context, peerID string) { +func (m *TimeBasedAuthSecretsManager) pushNewTURNAndRelayTokens(ctx context.Context, peerID string) { turnToken, err := m.turnHmacToken.GenerateToken(sha1.New) if err != nil { log.Errorf("failed to generate token for peer '%s': %s", peerID, err) @@ -201,10 +201,21 @@ func (m *TimeBasedAuthSecretsManager) pushNewTURNTokens(ctx context.Context, pee update := &proto.SyncResponse{ WiretrusteeConfig: &proto.WiretrusteeConfig{ Turns: turns, - // omit Relay to avoid updates there }, } + // workaround for the case when client is unable to handle turn and relay updates at different time + if m.relayCfg != nil { + token, err := m.GenerateRelayToken() + if err == nil { + update.WiretrusteeConfig.Relay = &proto.RelayConfig{ + Urls: m.relayCfg.Addresses, + TokenPayload: token.Payload, + TokenSignature: token.Signature, + } + } + } + log.WithContext(ctx).Debugf("sending new TURN credentials to peer %s", peerID) m.updateManager.SendUpdate(ctx, peerID, &UpdateMessage{Update: update}) } diff --git a/management/server/token_mgr_test.go b/management/server/token_mgr_test.go index 3e63346c2d0..2aafb9f6856 100644 --- a/management/server/token_mgr_test.go +++ b/management/server/token_mgr_test.go @@ -133,11 +133,14 @@ loop: } } if relay := update.Update.GetWiretrusteeConfig().GetRelay(); relay != nil { - relayUpdates++ - if relayUpdates == 1 { - firstRelayUpdate = relay - } else { - secondRelayUpdate = relay + // avoid updating on turn updates since they also send relay credentials + if update.Update.GetWiretrusteeConfig().GetTurns() == nil { + relayUpdates++ + if relayUpdates == 1 { + firstRelayUpdate = relay + } else { + secondRelayUpdate = relay + } } } } diff --git a/management/server/types/account.go b/management/server/types/account.go index 8fa61d700fa..f74d38cb6d4 100644 --- a/management/server/types/account.go +++ b/management/server/types/account.go @@ -1288,6 +1288,10 @@ func (a *Account) getNetworkResourceGroups(resourceID string) []*Group { func (a *Account) GetResourcePoliciesMap() map[string][]*Policy { resourcePolicies := make(map[string][]*Policy) for _, resource := range a.NetworkResources { + if !resource.Enabled { + continue + } + resourceAppliedPolicies := a.GetPoliciesForNetworkResource(resource.ID) resourcePolicies[resource.ID] = resourceAppliedPolicies } @@ -1301,6 +1305,10 @@ func (a *Account) GetNetworkResourcesRoutesToSync(ctx context.Context, peerID st allSourcePeers := make(map[string]struct{}, len(a.Peers)) for _, resource := range a.NetworkResources { + if !resource.Enabled { + continue + } + var addSourcePeers bool networkRoutingPeers, exists := routers[resource.NetworkID] @@ -1455,6 +1463,10 @@ func (a *Account) GetResourceRoutersMap() map[string]map[string]*routerTypes.Net routers := make(map[string]map[string]*routerTypes.NetworkRouter) for _, router := range a.NetworkRouters { + if !router.Enabled { + continue + } + if routers[router.NetworkID] == nil { routers[router.NetworkID] = make(map[string]*routerTypes.NetworkRouter) } diff --git a/management/server/types/account_test.go b/management/server/types/account_test.go index 389ab17f6c5..f8ab1d6274f 100644 --- a/management/server/types/account_test.go +++ b/management/server/types/account_test.go @@ -139,6 +139,11 @@ func setupTestAccount() *Account { AccountID: "accountID", Name: "network2", }, + { + ID: "network3ID", + AccountID: "accountID", + Name: "network3", + }, }, NetworkRouters: []*routerTypes.NetworkRouter{ { @@ -149,6 +154,7 @@ func setupTestAccount() *Account { PeerGroups: []string{}, Masquerade: false, Metric: 100, + Enabled: true, }, { ID: "router2ID", @@ -158,6 +164,7 @@ func setupTestAccount() *Account { PeerGroups: []string{}, Masquerade: false, Metric: 100, + Enabled: true, }, { ID: "router3ID", @@ -167,6 +174,7 @@ func setupTestAccount() *Account { PeerGroups: []string{}, Masquerade: false, Metric: 100, + Enabled: true, }, { ID: "router4ID", @@ -176,6 +184,7 @@ func setupTestAccount() *Account { PeerGroups: []string{"group1"}, Masquerade: false, Metric: 100, + Enabled: true, }, { ID: "router5ID", @@ -185,6 +194,7 @@ func setupTestAccount() *Account { PeerGroups: []string{"group2", "group3"}, Masquerade: false, Metric: 100, + Enabled: true, }, { ID: "router6ID", @@ -194,6 +204,17 @@ func setupTestAccount() *Account { PeerGroups: []string{"group4"}, Masquerade: false, Metric: 100, + Enabled: true, + }, + { + ID: "router6ID", + NetworkID: "network3ID", + AccountID: "accountID", + Peer: "", + PeerGroups: []string{"group6"}, + Masquerade: false, + Metric: 100, + Enabled: false, }, }, NetworkResources: []*resourceTypes.NetworkResource{ @@ -201,21 +222,31 @@ func setupTestAccount() *Account { ID: "resource1ID", AccountID: "accountID", NetworkID: "network1ID", + Enabled: true, }, { ID: "resource2ID", AccountID: "accountID", NetworkID: "network2ID", + Enabled: true, }, { ID: "resource3ID", AccountID: "accountID", NetworkID: "network1ID", + Enabled: true, }, { ID: "resource4ID", AccountID: "accountID", NetworkID: "network1ID", + Enabled: true, + }, + { + ID: "resource5ID", + AccountID: "accountID", + NetworkID: "network3ID", + Enabled: false, }, }, Policies: []*Policy{ @@ -281,6 +312,17 @@ func setupTestAccount() *Account { }, }, }, + { + ID: "policy6ID", + AccountID: "accountID", + Enabled: true, + Rules: []*PolicyRule{ + { + ID: "rule6ID", + Enabled: true, + }, + }, + }, }, } } @@ -302,6 +344,8 @@ func Test_GetResourceRoutersMap(t *testing.T) { require.Equal(t, 2, len(routers["network2ID"])) require.NotNil(t, routers["network2ID"]["peer2"]) require.NotNil(t, routers["network2ID"]["peer41"]) + + require.Equal(t, 0, len(routers["network3ID"])) } func Test_GetResourcePoliciesMap(t *testing.T) { @@ -312,6 +356,7 @@ func Test_GetResourcePoliciesMap(t *testing.T) { require.Equal(t, 1, len(policies["resource2ID"])) require.Equal(t, 2, len(policies["resource3ID"])) require.Equal(t, 1, len(policies["resource4ID"])) + require.Equal(t, 0, len(policies["resource5ID"])) } func Test_AddNetworksRoutingPeersAddsMissingPeers(t *testing.T) { @@ -476,6 +521,7 @@ func getBasicAccountsWithResource() *Account { PeerGroups: []string{}, Masquerade: false, Metric: 100, + Enabled: true, }, }, NetworkResources: []*resourceTypes.NetworkResource{ @@ -486,6 +532,7 @@ func getBasicAccountsWithResource() *Account { Address: "10.10.10.0/24", Prefix: netip.MustParsePrefix("10.10.10.0/24"), Type: resourceTypes.NetworkResourceType("subnet"), + Enabled: true, }, }, Policies: []*Policy{