do not send resource policies map over the wire

Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
This commit is contained in:
Dmitri Dolguikh
2026-07-21 19:27:16 +02:00
parent db80f9361c
commit 969dd04615
6 changed files with 917 additions and 821 deletions

View File

@@ -173,23 +173,14 @@ func DecodeEnvelope(env *proto.NetworkMapEnvelope) (*types.NetworkMapComponents,
}
}
// Phase 8: resource_policies_map (resource seq id → list of *types.Policy
// pointers from the decoded policies slice). Resource ID is synthesized
// the same way as in decodeNetworkResource.
for resourceID, ids := range full.ResourcePoliciesMap {
if len(ids.Ids) == 0 {
continue
// Phase 8: resource_policies_map
for _, p := range c.Policies {
rule := p.Rules[0] // there's always only one rule
if rule.SourceResource.Type != types.ResourceTypePeer && rule.SourceResource.ID != "" {
c.ResourcePoliciesMap[rule.SourceResource.ID] = append(c.ResourcePoliciesMap[rule.SourceResource.ID], p)
}
policies := make([]*types.Policy, 0, len(ids.Ids))
for _, id := range ids.Ids {
if p, ok := policyByID[id]; ok {
policies = append(policies, p)
} else {
log.WithField("policy id", id).Error("unrecognized policy when decoding resource policies")
}
}
if len(policies) > 0 {
c.ResourcePoliciesMap[resourceID] = policies
if rule.SourceResource.Type != types.ResourceTypePeer && rule.DestinationResource.Type != "" {
c.ResourcePoliciesMap[rule.SourceResource.ID] = append(c.ResourcePoliciesMap[rule.SourceResource.ID], p)
}
}
@@ -344,11 +335,27 @@ func resourceFromProto(r *proto.ResourceCompact, peerIDByIndex []string) types.R
if r == nil {
return types.Resource{}
}
out := types.Resource{Type: types.ResourceType(r.Type)}
if r.PeerIndexSet && int(r.PeerIndex) < len(peerIDByIndex) {
out.ID = peerIDByIndex[r.PeerIndex]
t, ok := proto.ResourceCompactType_name[int32(r.Type)]
if !ok || r.Type == proto.ResourceCompactType_unknown_type {
return types.Resource{}
}
if r.Type == proto.ResourceCompactType_peer && int(r.GetPeerIndex()) >= len(peerIDByIndex) {
return types.Resource{}
}
if r.Type == proto.ResourceCompactType_peer && int(r.GetPeerIndex()) < len(peerIDByIndex) {
return types.Resource{
Type: types.ResourceTypePeer,
ID: peerIDByIndex[int(r.GetPeerIndex())],
}
}
return types.Resource{
Type: types.ResourceType(t),
ID: r.GetId(),
}
return out
}
// authorizedGroupsFromProto inverts encodeAuthorizedGroups: the wire form

View File

@@ -0,0 +1,40 @@
package networkmap
import (
"testing"
"github.com/netbirdio/netbird/shared/management/proto"
"github.com/netbirdio/netbird/shared/management/types"
"github.com/stretchr/testify/assert"
)
func TestDecodePolicy(t *testing.T) {
assert.Equal(t,
resourceFromProto(
&proto.ResourceCompact{Type: proto.ResourceCompactType_peer, ResourceId: &proto.ResourceCompact_PeerIndex{PeerIndex: uint32(1)}},
[]string{"invalid-id-0", "valid-id", "invalid-id-2"}),
types.Resource{Type: "peer", ID: "valid-id"})
// check invalid peer index returns an empty resource
assert.Equal(t,
resourceFromProto(
&proto.ResourceCompact{Type: proto.ResourceCompactType_peer, ResourceId: &proto.ResourceCompact_PeerIndex{PeerIndex: uint32(100)}},
[]string{"invalid-id-0", "valid-id", "invalid-id-2"}),
types.Resource{})
assert.Equal(t,
resourceFromProto(
&proto.ResourceCompact{Type: proto.ResourceCompactType_domain, ResourceId: &proto.ResourceCompact_Id{Id: "domain"}}, []string{}),
types.Resource{Type: "domain", ID: "domain"})
assert.Equal(t,
resourceFromProto(
&proto.ResourceCompact{Type: proto.ResourceCompactType_host, ResourceId: &proto.ResourceCompact_Id{Id: "host"}}, []string{}),
types.Resource{Type: "host", ID: "host"})
assert.Equal(t,
resourceFromProto(
&proto.ResourceCompact{Type: proto.ResourceCompactType_subnet, ResourceId: &proto.ResourceCompact_Id{Id: "subnet"}}, []string{}),
types.Resource{Type: "subnet", ID: "subnet"})
// an unknown resource type return an empty resource
assert.Equal(t,
resourceFromProto(
&proto.ResourceCompact{Type: proto.ResourceCompactType_unknown_type, ResourceId: &proto.ResourceCompact_Id{Id: "boom"}}, []string{}),
types.Resource{})
}