mirror of
https://github.com/netbirdio/netbird.git
synced 2026-05-03 15:46:38 +00:00
Compare commits
6 Commits
fix/dns-ha
...
fix/up-seq
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55d8b4e42c | ||
|
|
9b8f7d75b3 | ||
|
|
57f3af57f4 | ||
|
|
dc30dcacce | ||
|
|
2c87fa6236 | ||
|
|
ec8d83ade4 |
@@ -33,6 +33,7 @@ type ErrListener interface {
|
|||||||
// the backend want to show an url for the user
|
// the backend want to show an url for the user
|
||||||
type URLOpener interface {
|
type URLOpener interface {
|
||||||
Open(string)
|
Open(string)
|
||||||
|
OnLoginSuccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auth can register or login new client
|
// Auth can register or login new client
|
||||||
@@ -181,6 +182,11 @@ func (a *Auth) login(urlOpener URLOpener) error {
|
|||||||
|
|
||||||
err = a.withBackOff(a.ctx, func() error {
|
err = a.withBackOff(a.ctx, func() error {
|
||||||
err := internal.Login(a.ctx, a.config, "", jwtToken)
|
err := internal.Login(a.ctx, a.config, "", jwtToken)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
go urlOpener.OnLoginSuccess()
|
||||||
|
}
|
||||||
|
|
||||||
if s, ok := gstatus.FromError(err); ok && (s.Code() == codes.InvalidArgument || s.Code() == codes.PermissionDenied) {
|
if s, ok := gstatus.FromError(err); ok && (s.Code() == codes.InvalidArgument || s.Code() == codes.PermissionDenied) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ func FlagNameToEnvVar(cmdFlag string, prefix string) string {
|
|||||||
|
|
||||||
// DialClientGRPCServer returns client connection to the daemon server.
|
// DialClientGRPCServer returns client connection to the daemon server.
|
||||||
func DialClientGRPCServer(ctx context.Context, addr string) (*grpc.ClientConn, error) {
|
func DialClientGRPCServer(ctx context.Context, addr string) (*grpc.ClientConn, error) {
|
||||||
ctx, cancel := context.WithTimeout(ctx, time.Second*3)
|
ctx, cancel := context.WithTimeout(ctx, time.Second*10)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
return grpc.DialContext(
|
return grpc.DialContext(
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ func runInDaemonMode(ctx context.Context, cmd *cobra.Command, pm *profilemanager
|
|||||||
|
|
||||||
client := proto.NewDaemonServiceClient(conn)
|
client := proto.NewDaemonServiceClient(conn)
|
||||||
|
|
||||||
status, err := client.Status(ctx, &proto.StatusRequest{})
|
status, err := client.Status(ctx, &proto.StatusRequest{WaitForConnectingShift: true})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to get daemon status: %v", err)
|
return fmt.Errorf("unable to get daemon status: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.6
|
// protoc-gen-go v1.36.6
|
||||||
// protoc v5.29.3
|
// protoc v3.21.9
|
||||||
// source: daemon.proto
|
// source: daemon.proto
|
||||||
|
|
||||||
package proto
|
package proto
|
||||||
@@ -791,11 +791,12 @@ func (*UpResponse) Descriptor() ([]byte, []int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type StatusRequest struct {
|
type StatusRequest struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
GetFullPeerStatus bool `protobuf:"varint,1,opt,name=getFullPeerStatus,proto3" json:"getFullPeerStatus,omitempty"`
|
GetFullPeerStatus bool `protobuf:"varint,1,opt,name=getFullPeerStatus,proto3" json:"getFullPeerStatus,omitempty"`
|
||||||
ShouldRunProbes bool `protobuf:"varint,2,opt,name=shouldRunProbes,proto3" json:"shouldRunProbes,omitempty"`
|
ShouldRunProbes bool `protobuf:"varint,2,opt,name=shouldRunProbes,proto3" json:"shouldRunProbes,omitempty"`
|
||||||
unknownFields protoimpl.UnknownFields
|
WaitForConnectingShift bool `protobuf:"varint,3,opt,name=waitForConnectingShift,proto3" json:"waitForConnectingShift,omitempty"`
|
||||||
sizeCache protoimpl.SizeCache
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *StatusRequest) Reset() {
|
func (x *StatusRequest) Reset() {
|
||||||
@@ -842,6 +843,13 @@ func (x *StatusRequest) GetShouldRunProbes() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *StatusRequest) GetWaitForConnectingShift() bool {
|
||||||
|
if x != nil {
|
||||||
|
return x.WaitForConnectingShift
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
type StatusResponse struct {
|
type StatusResponse struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
// status of the server.
|
// status of the server.
|
||||||
@@ -4673,10 +4681,11 @@ const file_daemon_proto_rawDesc = "" +
|
|||||||
"\f_profileNameB\v\n" +
|
"\f_profileNameB\v\n" +
|
||||||
"\t_username\"\f\n" +
|
"\t_username\"\f\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"UpResponse\"g\n" +
|
"UpResponse\"\x9f\x01\n" +
|
||||||
"\rStatusRequest\x12,\n" +
|
"\rStatusRequest\x12,\n" +
|
||||||
"\x11getFullPeerStatus\x18\x01 \x01(\bR\x11getFullPeerStatus\x12(\n" +
|
"\x11getFullPeerStatus\x18\x01 \x01(\bR\x11getFullPeerStatus\x12(\n" +
|
||||||
"\x0fshouldRunProbes\x18\x02 \x01(\bR\x0fshouldRunProbes\"\x82\x01\n" +
|
"\x0fshouldRunProbes\x18\x02 \x01(\bR\x0fshouldRunProbes\x126\n" +
|
||||||
|
"\x16waitForConnectingShift\x18\x03 \x01(\bR\x16waitForConnectingShift\"\x82\x01\n" +
|
||||||
"\x0eStatusResponse\x12\x16\n" +
|
"\x0eStatusResponse\x12\x16\n" +
|
||||||
"\x06status\x18\x01 \x01(\tR\x06status\x122\n" +
|
"\x06status\x18\x01 \x01(\tR\x06status\x122\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
|
|||||||
@@ -186,6 +186,7 @@ message UpResponse {}
|
|||||||
message StatusRequest{
|
message StatusRequest{
|
||||||
bool getFullPeerStatus = 1;
|
bool getFullPeerStatus = 1;
|
||||||
bool shouldRunProbes = 2;
|
bool shouldRunProbes = 2;
|
||||||
|
bool waitForConnectingShift = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message StatusResponse{
|
message StatusResponse{
|
||||||
|
|||||||
@@ -119,14 +119,12 @@ func (s *Server) Start() error {
|
|||||||
// if current state contains any error, return it
|
// if current state contains any error, return it
|
||||||
// in all other cases we can continue execution only if status is idle and up command was
|
// in all other cases we can continue execution only if status is idle and up command was
|
||||||
// not in the progress or already successfully established connection.
|
// not in the progress or already successfully established connection.
|
||||||
status, err := state.Status()
|
_, err := state.Status()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if status != internal.StatusIdle {
|
state.Set(internal.StatusConnecting)
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(s.rootCtx)
|
ctx, cancel := context.WithCancel(s.rootCtx)
|
||||||
s.actCancel = cancel
|
s.actCancel = cancel
|
||||||
@@ -961,6 +959,33 @@ func (s *Server) sendLogoutRequestWithConfig(ctx context.Context, config *profil
|
|||||||
return mgmClient.Logout()
|
return mgmClient.Logout()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func waitStateShift(ctx context.Context) {
|
||||||
|
timer := time.NewTimer(5 * time.Second)
|
||||||
|
defer timer.Stop()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
log.Warnf("context done while waiting for state shift: %v", ctx.Err())
|
||||||
|
timer.Stop()
|
||||||
|
return
|
||||||
|
case <-timer.C:
|
||||||
|
log.Warnf("state shift timed out")
|
||||||
|
timer.Stop()
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
status, err := internal.CtxGetState(ctx).Status()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to get status: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if status != internal.StatusConnecting {
|
||||||
|
log.Infof("state shifting status: %v", status)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Status returns the daemon status
|
// Status returns the daemon status
|
||||||
func (s *Server) Status(
|
func (s *Server) Status(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
@@ -973,6 +998,10 @@ func (s *Server) Status(
|
|||||||
s.mutex.Lock()
|
s.mutex.Lock()
|
||||||
defer s.mutex.Unlock()
|
defer s.mutex.Unlock()
|
||||||
|
|
||||||
|
if msg.WaitForConnectingShift {
|
||||||
|
waitStateShift(s.rootCtx)
|
||||||
|
}
|
||||||
|
|
||||||
status, err := internal.CtxGetState(s.rootCtx).Status()
|
status, err := internal.CtxGetState(s.rootCtx).Status()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -529,7 +529,7 @@ func (s *serviceClient) getSettingsForm() *widget.Form {
|
|||||||
var req proto.SetConfigRequest
|
var req proto.SetConfigRequest
|
||||||
req.ProfileName = activeProf.Name
|
req.ProfileName = activeProf.Name
|
||||||
req.Username = currUser.Username
|
req.Username = currUser.Username
|
||||||
|
|
||||||
if iMngURL != "" {
|
if iMngURL != "" {
|
||||||
req.ManagementUrl = iMngURL
|
req.ManagementUrl = iMngURL
|
||||||
}
|
}
|
||||||
@@ -563,27 +563,28 @@ func (s *serviceClient) getSettingsForm() *widget.Form {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
status, err := conn.Status(s.ctx, &proto.StatusRequest{})
|
go func() {
|
||||||
if err != nil {
|
status, err := conn.Status(s.ctx, &proto.StatusRequest{})
|
||||||
log.Errorf("get service status: %v", err)
|
|
||||||
dialog.ShowError(fmt.Errorf("Failed to get service status: %v", err), s.wSettings)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if status.Status == string(internal.StatusConnected) {
|
|
||||||
// run down & up
|
|
||||||
_, err = conn.Down(s.ctx, &proto.DownRequest{})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("down service: %v", err)
|
log.Errorf("get service status: %v", err)
|
||||||
}
|
dialog.ShowError(fmt.Errorf("Failed to get service status: %v", err), s.wSettings)
|
||||||
|
|
||||||
_, err = conn.Up(s.ctx, &proto.UpRequest{})
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("up service: %v", err)
|
|
||||||
dialog.ShowError(fmt.Errorf("Failed to reconnect: %v", err), s.wSettings)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
if status.Status == string(internal.StatusConnected) {
|
||||||
|
// run down & up
|
||||||
|
_, err = conn.Down(s.ctx, &proto.DownRequest{})
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("down service: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = conn.Up(s.ctx, &proto.UpRequest{})
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("up service: %v", err)
|
||||||
|
dialog.ShowError(fmt.Errorf("Failed to reconnect: %v", err), s.wSettings)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
OnCancel: func() {
|
OnCancel: func() {
|
||||||
|
|||||||
@@ -302,7 +302,11 @@ func (a *Account) GetPeerNetworkMap(
|
|||||||
var zones []nbdns.CustomZone
|
var zones []nbdns.CustomZone
|
||||||
|
|
||||||
if peersCustomZone.Domain != "" {
|
if peersCustomZone.Domain != "" {
|
||||||
zones = append(zones, peersCustomZone)
|
records := filterZoneRecordsForPeers(peer, peersCustomZone, peersToConnect)
|
||||||
|
zones = append(zones, nbdns.CustomZone{
|
||||||
|
Domain: peersCustomZone.Domain,
|
||||||
|
Records: records,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
dnsUpdate.CustomZones = zones
|
dnsUpdate.CustomZones = zones
|
||||||
dnsUpdate.NameServerGroups = getPeerNSGroups(a, peerID)
|
dnsUpdate.NameServerGroups = getPeerNSGroups(a, peerID)
|
||||||
@@ -1651,3 +1655,24 @@ func peerSupportsPortRanges(peerVer string) bool {
|
|||||||
meetMinVer, err := posture.MeetsMinVersion(firewallRuleMinPortRangesVer, peerVer)
|
meetMinVer, err := posture.MeetsMinVersion(firewallRuleMinPortRangesVer, peerVer)
|
||||||
return err == nil && meetMinVer
|
return err == nil && meetMinVer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// filterZoneRecordsForPeers filters DNS records to only include peers to connect.
|
||||||
|
func filterZoneRecordsForPeers(peer *nbpeer.Peer, customZone nbdns.CustomZone, peersToConnect []*nbpeer.Peer) []nbdns.SimpleRecord {
|
||||||
|
filteredRecords := make([]nbdns.SimpleRecord, 0, len(customZone.Records))
|
||||||
|
peerIPs := make(map[string]struct{})
|
||||||
|
|
||||||
|
// Add peer's own IP to include its own DNS records
|
||||||
|
peerIPs[peer.IP.String()] = struct{}{}
|
||||||
|
|
||||||
|
for _, peerToConnect := range peersToConnect {
|
||||||
|
peerIPs[peerToConnect.IP.String()] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, record := range customZone.Records {
|
||||||
|
if _, exists := peerIPs[record.RData]; exists {
|
||||||
|
filteredRecords = append(filteredRecords, record)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filteredRecords
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,14 +2,17 @@ package types
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"slices"
|
"slices"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/miekg/dns"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
nbdns "github.com/netbirdio/netbird/dns"
|
||||||
resourceTypes "github.com/netbirdio/netbird/management/server/networks/resources/types"
|
resourceTypes "github.com/netbirdio/netbird/management/server/networks/resources/types"
|
||||||
routerTypes "github.com/netbirdio/netbird/management/server/networks/routers/types"
|
routerTypes "github.com/netbirdio/netbird/management/server/networks/routers/types"
|
||||||
networkTypes "github.com/netbirdio/netbird/management/server/networks/types"
|
networkTypes "github.com/netbirdio/netbird/management/server/networks/types"
|
||||||
@@ -835,3 +838,109 @@ func Test_NetworksNetMapGenShouldExcludeOtherRouters(t *testing.T) {
|
|||||||
assert.Len(t, networkResourcesRoutes, 1, "expected network resource route don't match")
|
assert.Len(t, networkResourcesRoutes, 1, "expected network resource route don't match")
|
||||||
assert.Len(t, sourcePeers, 2, "expected source peers don't match")
|
assert.Len(t, sourcePeers, 2, "expected source peers don't match")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_FilterZoneRecordsForPeers(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
peer *nbpeer.Peer
|
||||||
|
customZone nbdns.CustomZone
|
||||||
|
peersToConnect []*nbpeer.Peer
|
||||||
|
expectedRecords []nbdns.SimpleRecord
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty peers to connect",
|
||||||
|
customZone: nbdns.CustomZone{
|
||||||
|
Domain: "netbird.cloud.",
|
||||||
|
Records: []nbdns.SimpleRecord{
|
||||||
|
{Name: "peer1.netbird.cloud", Type: int(dns.TypeA), Class: nbdns.DefaultClass, TTL: 300, RData: "10.0.0.1"},
|
||||||
|
{Name: "router.netbird.cloud", Type: int(dns.TypeA), Class: nbdns.DefaultClass, TTL: 300, RData: "10.0.0.100"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
peersToConnect: []*nbpeer.Peer{},
|
||||||
|
peer: &nbpeer.Peer{ID: "router", IP: net.ParseIP("10.0.0.100")},
|
||||||
|
expectedRecords: []nbdns.SimpleRecord{
|
||||||
|
{Name: "router.netbird.cloud", Type: int(dns.TypeA), Class: nbdns.DefaultClass, TTL: 300, RData: "10.0.0.100"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple peers multiple records match",
|
||||||
|
customZone: nbdns.CustomZone{
|
||||||
|
Domain: "netbird.cloud.",
|
||||||
|
Records: func() []nbdns.SimpleRecord {
|
||||||
|
var records []nbdns.SimpleRecord
|
||||||
|
for i := 1; i <= 100; i++ {
|
||||||
|
records = append(records, nbdns.SimpleRecord{
|
||||||
|
Name: fmt.Sprintf("peer%d.netbird.cloud", i),
|
||||||
|
Type: int(dns.TypeA),
|
||||||
|
Class: nbdns.DefaultClass,
|
||||||
|
TTL: 300,
|
||||||
|
RData: fmt.Sprintf("10.0.%d.%d", i/256, i%256),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return records
|
||||||
|
}(),
|
||||||
|
},
|
||||||
|
peersToConnect: func() []*nbpeer.Peer {
|
||||||
|
var peers []*nbpeer.Peer
|
||||||
|
for _, i := range []int{1, 5, 10, 25, 50, 75, 100} {
|
||||||
|
peers = append(peers, &nbpeer.Peer{
|
||||||
|
ID: fmt.Sprintf("peer%d", i),
|
||||||
|
IP: net.ParseIP(fmt.Sprintf("10.0.%d.%d", i/256, i%256)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return peers
|
||||||
|
}(),
|
||||||
|
peer: &nbpeer.Peer{ID: "router", IP: net.ParseIP("10.0.0.100")},
|
||||||
|
expectedRecords: func() []nbdns.SimpleRecord {
|
||||||
|
var records []nbdns.SimpleRecord
|
||||||
|
for _, i := range []int{1, 5, 10, 25, 50, 75, 100} {
|
||||||
|
records = append(records, nbdns.SimpleRecord{
|
||||||
|
Name: fmt.Sprintf("peer%d.netbird.cloud", i),
|
||||||
|
Type: int(dns.TypeA),
|
||||||
|
Class: nbdns.DefaultClass,
|
||||||
|
TTL: 300,
|
||||||
|
RData: fmt.Sprintf("10.0.%d.%d", i/256, i%256),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return records
|
||||||
|
}(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "peers with multiple DNS labels",
|
||||||
|
customZone: nbdns.CustomZone{
|
||||||
|
Domain: "netbird.cloud.",
|
||||||
|
Records: []nbdns.SimpleRecord{
|
||||||
|
{Name: "peer1.netbird.cloud", Type: int(dns.TypeA), Class: nbdns.DefaultClass, TTL: 300, RData: "10.0.0.1"},
|
||||||
|
{Name: "peer1-alt.netbird.cloud", Type: int(dns.TypeA), Class: nbdns.DefaultClass, TTL: 300, RData: "10.0.0.1"},
|
||||||
|
{Name: "peer1-backup.netbird.cloud", Type: int(dns.TypeA), Class: nbdns.DefaultClass, TTL: 300, RData: "10.0.0.1"},
|
||||||
|
{Name: "peer2.netbird.cloud", Type: int(dns.TypeA), Class: nbdns.DefaultClass, TTL: 300, RData: "10.0.0.2"},
|
||||||
|
{Name: "peer2-service.netbird.cloud", Type: int(dns.TypeA), Class: nbdns.DefaultClass, TTL: 300, RData: "10.0.0.2"},
|
||||||
|
{Name: "peer3.netbird.cloud", Type: int(dns.TypeA), Class: nbdns.DefaultClass, TTL: 300, RData: "10.0.0.3"},
|
||||||
|
{Name: "peer3-alt.netbird.cloud", Type: int(dns.TypeA), Class: nbdns.DefaultClass, TTL: 300, RData: "10.0.0.3"},
|
||||||
|
{Name: "router.netbird.cloud", Type: int(dns.TypeA), Class: nbdns.DefaultClass, TTL: 300, RData: "10.0.0.100"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
peersToConnect: []*nbpeer.Peer{
|
||||||
|
{ID: "peer1", IP: net.ParseIP("10.0.0.1"), DNSLabel: "peer1", ExtraDNSLabels: []string{"peer1-alt", "peer1-backup"}},
|
||||||
|
{ID: "peer2", IP: net.ParseIP("10.0.0.2"), DNSLabel: "peer2", ExtraDNSLabels: []string{"peer2-service"}},
|
||||||
|
},
|
||||||
|
peer: &nbpeer.Peer{ID: "router", IP: net.ParseIP("10.0.0.100")},
|
||||||
|
expectedRecords: []nbdns.SimpleRecord{
|
||||||
|
{Name: "peer1.netbird.cloud", Type: int(dns.TypeA), Class: nbdns.DefaultClass, TTL: 300, RData: "10.0.0.1"},
|
||||||
|
{Name: "peer1-alt.netbird.cloud", Type: int(dns.TypeA), Class: nbdns.DefaultClass, TTL: 300, RData: "10.0.0.1"},
|
||||||
|
{Name: "peer1-backup.netbird.cloud", Type: int(dns.TypeA), Class: nbdns.DefaultClass, TTL: 300, RData: "10.0.0.1"},
|
||||||
|
{Name: "peer2.netbird.cloud", Type: int(dns.TypeA), Class: nbdns.DefaultClass, TTL: 300, RData: "10.0.0.2"},
|
||||||
|
{Name: "peer2-service.netbird.cloud", Type: int(dns.TypeA), Class: nbdns.DefaultClass, TTL: 300, RData: "10.0.0.2"},
|
||||||
|
{Name: "router.netbird.cloud", Type: int(dns.TypeA), Class: nbdns.DefaultClass, TTL: 300, RData: "10.0.0.100"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := filterZoneRecordsForPeers(tt.peer, tt.customZone, tt.peersToConnect)
|
||||||
|
assert.Equal(t, len(tt.expectedRecords), len(result))
|
||||||
|
assert.ElementsMatch(t, tt.expectedRecords, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user