mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-12 16:39:09 +02:00
include legacy path in golden test
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
//go:build nmapequiv
|
||||
|
||||
package legacynmap
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,16 +1,3 @@
|
||||
//go:build nmapequiv
|
||||
|
||||
// Package legacynmap is a frozen copy of main's Account → NetworkMapComponents →
|
||||
// NetworkMap → proto path, used only by the main-vs-branch equivalence test.
|
||||
// It is build-tagged so it never compiles into production binaries, and it lives
|
||||
// in its own package so it cannot reach this tree's unexported helpers — a
|
||||
// divergence can therefore never be hidden by the two sides sharing code.
|
||||
//
|
||||
// Delete this package once the nmdata refactor is validated.
|
||||
//
|
||||
// Types below are aliased rather than copied because they are byte-identical
|
||||
// between main and this branch. Anything that drifted is copied instead; see
|
||||
// converters.go and copied_funcs.go.
|
||||
package legacynmap
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//go:build nmapequiv
|
||||
|
||||
package legacynmap
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//go:build nmapequiv
|
||||
|
||||
package legacynmap
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//go:build nmapequiv
|
||||
|
||||
package legacynmap
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
// Package legacynmap holds a frozen copy of main's network-map computation,
|
||||
// used only by the main-vs-branch proto equivalence test. All real content is
|
||||
// behind the nmapequiv build tag; this file exists so the package is still valid
|
||||
// for untagged builds and `go test ./...`.
|
||||
// Package legacynmap is a frozen copy of main's Account → NetworkMapComponents
|
||||
// → NetworkMap → proto path. It exists only to measure this tree against main:
|
||||
// the proto-equivalence test runs it over a production database copy, and the
|
||||
// nmaptest golden suite runs it as a third mode so every case pins all three
|
||||
// shapes to one expectation.
|
||||
//
|
||||
// It lives in its own package so it cannot reach this tree's unexported
|
||||
// helpers — a divergence can therefore never be hidden by the two sides
|
||||
// sharing code. Nothing in production imports it.
|
||||
//
|
||||
// Types are aliased rather than copied where they are byte-identical between
|
||||
// main and this branch. Anything that drifted is copied instead; see
|
||||
// converters.go and copied_funcs.go.
|
||||
//
|
||||
// Delete this package once the nmdata refactor is validated.
|
||||
package legacynmap
|
||||
|
||||
@@ -160,6 +160,17 @@ func checkAccount(ctx context.Context, t *testing.T, nmStore *networkmapdb.Netwo
|
||||
routers := account.GetResourceRoutersMap()
|
||||
groupUsers := account.GetActiveGroupUsers()
|
||||
|
||||
// The reverse-proxy ACLs are synthesised, never persisted. Both new paths
|
||||
// derive them inside the twin; main derived them in the controller, onto
|
||||
// the account, before the resource-policy map. The legacy side therefore
|
||||
// runs on its own view of the policies — a shallow copy so the account the
|
||||
// other two paths read stays untouched and cannot double-count them.
|
||||
legacyAccount := *account
|
||||
if synth := legacynmap.SynthesizeProxyPolicies(account); len(synth) > 0 {
|
||||
legacyAccount.Policies = append(slices.Clone(account.Policies), synth...)
|
||||
}
|
||||
legacyResourcePolicies := legacyAccount.GetResourcePoliciesMap()
|
||||
|
||||
settings := account.Settings
|
||||
if settings == nil {
|
||||
settings = &types.Settings{}
|
||||
@@ -200,7 +211,7 @@ func checkAccount(ctx context.Context, t *testing.T, nmStore *networkmapdb.Netwo
|
||||
|
||||
// LEGACY PATH — main's frozen copy.
|
||||
legacyNM := legacynmap.GetPeerNetworkMapFromComponents(
|
||||
account, ctx, peerID, nbdns.CustomZone{}, nil, validated, resourcePolicies, routers, nil, groupUsers,
|
||||
&legacyAccount, ctx, peerID, nbdns.CustomZone{}, nil, validated, legacyResourcePolicies, routers, nil, groupUsers,
|
||||
)
|
||||
if legacyNM == nil {
|
||||
t.Fatalf("after %d peers: account=%s peer=%s legacy NetworkMap nil, new non-nil", stats.peersChecked, account.Id, peerID)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//go:build nmapequiv
|
||||
|
||||
package legacynmap
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//go:build nmapequiv
|
||||
|
||||
package legacynmap
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//go:build nmapequiv
|
||||
|
||||
package legacynmap
|
||||
|
||||
import (
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
package legacynmap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/netbirdio/netbird/management/internals/modules/reverseproxy/service"
|
||||
nbpeer "github.com/netbirdio/netbird/management/server/peer"
|
||||
sharedtypes "github.com/netbirdio/netbird/shared/management/types"
|
||||
)
|
||||
|
||||
// SynthesizeProxyPolicies is main's Account.InjectProxyPolicies, frozen. On
|
||||
// main the network-map controller called it on the account before computing,
|
||||
// so a comparison that starts from the account has to apply it too. It returns
|
||||
// the policies instead of appending them, so the caller can measure the legacy
|
||||
// path without mutating the account the other paths share.
|
||||
func SynthesizeProxyPolicies(a *Account) []*Policy {
|
||||
if len(a.Services) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
proxyPeersByCluster := a.GetProxyPeers()
|
||||
if len(proxyPeersByCluster) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var out []*Policy
|
||||
for _, svc := range a.Services {
|
||||
if svc == nil || !svc.Enabled {
|
||||
continue
|
||||
}
|
||||
|
||||
proxyPeers := proxyPeersByCluster[svc.ProxyCluster]
|
||||
for _, target := range svc.Targets {
|
||||
if target == nil || !target.Enabled {
|
||||
continue
|
||||
}
|
||||
port, ok := legacyTargetPort(target)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
path := ""
|
||||
if target.Path != nil {
|
||||
path = *target.Path
|
||||
}
|
||||
for _, proxyPeer := range proxyPeers {
|
||||
out = append(out, legacyProxyPolicy(svc, target, proxyPeer, port, path))
|
||||
}
|
||||
}
|
||||
|
||||
out = append(out, legacyPrivateServicePolicies(a, svc, proxyPeers)...)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func legacyPrivateServicePolicies(a *Account, svc *service.Service, proxyPeers []*nbpeer.Peer) []*Policy {
|
||||
if !svc.Private || len(svc.AccessGroups) == 0 || len(proxyPeers) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
sources := make([]string, 0, len(svc.AccessGroups))
|
||||
for _, groupID := range svc.AccessGroups {
|
||||
if _, ok := a.Groups[groupID]; ok {
|
||||
sources = append(sources, groupID)
|
||||
}
|
||||
}
|
||||
if len(sources) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
out := make([]*Policy, 0, len(proxyPeers))
|
||||
for _, proxyPeer := range proxyPeers {
|
||||
policyID := fmt.Sprintf("private-access-%s-%s", svc.ID, proxyPeer.ID)
|
||||
out = append(out, &Policy{
|
||||
ID: policyID,
|
||||
Name: fmt.Sprintf("Private Access to %s", svc.Name),
|
||||
Enabled: true,
|
||||
Rules: []*PolicyRule{
|
||||
{
|
||||
ID: policyID,
|
||||
PolicyID: policyID,
|
||||
Name: fmt.Sprintf("Allow access groups to reach %s", svc.Name),
|
||||
Enabled: true,
|
||||
Sources: append([]string(nil), sources...),
|
||||
DestinationResource: Resource{
|
||||
ID: proxyPeer.ID,
|
||||
Type: ResourceTypePeer,
|
||||
},
|
||||
Bidirectional: false,
|
||||
Protocol: PolicyRuleProtocolTCP,
|
||||
Action: PolicyTrafficActionAccept,
|
||||
PortRanges: []RulePortRange{
|
||||
{Start: 80, End: 80},
|
||||
{Start: 443, End: 443},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func legacyProxyPolicy(svc *service.Service, target *service.Target, proxyPeer *nbpeer.Peer, port uint16, path string) *Policy {
|
||||
policyID := fmt.Sprintf("proxy-access-%s-%s-%s", svc.ID, proxyPeer.ID, path)
|
||||
|
||||
protocol := PolicyRuleProtocolTCP
|
||||
if svc.Mode == service.ModeUDP {
|
||||
protocol = sharedtypes.PolicyRuleProtocolUDP
|
||||
}
|
||||
|
||||
return &Policy{
|
||||
ID: policyID,
|
||||
Name: fmt.Sprintf("Proxy Access to %s", svc.Name),
|
||||
Enabled: true,
|
||||
Rules: []*PolicyRule{
|
||||
{
|
||||
ID: policyID,
|
||||
PolicyID: policyID,
|
||||
Name: fmt.Sprintf("Allow access to %s", svc.Name),
|
||||
Enabled: true,
|
||||
SourceResource: Resource{
|
||||
ID: proxyPeer.ID,
|
||||
Type: ResourceTypePeer,
|
||||
},
|
||||
DestinationResource: Resource{
|
||||
ID: target.TargetId,
|
||||
Type: sharedtypes.ResourceType(target.TargetType),
|
||||
},
|
||||
Bidirectional: false,
|
||||
Protocol: protocol,
|
||||
Action: PolicyTrafficActionAccept,
|
||||
PortRanges: []RulePortRange{{Start: port, End: port}},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func legacyTargetPort(target *service.Target) (uint16, bool) {
|
||||
if target.Port != 0 {
|
||||
return target.Port, true
|
||||
}
|
||||
|
||||
switch target.Protocol {
|
||||
case "https", "tls":
|
||||
return 443, true
|
||||
case "http":
|
||||
return 80, true
|
||||
default:
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user