mirror of
https://github.com/netbirdio/netbird.git
synced 2026-05-06 00:56:39 +00:00
Compare commits
19 Commits
v0.43.2
...
feature/re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26d21b2071 | ||
|
|
edb30447c1 | ||
|
|
52259fc15e | ||
|
|
ee1cec47b3 | ||
|
|
efb0edfc4c | ||
|
|
20f59ddecb | ||
|
|
927be2b7d2 | ||
|
|
d455f66564 | ||
|
|
3dea2dec5c | ||
|
|
5893b69f86 | ||
|
|
2f34e984b0 | ||
|
|
d5b52e86b6 | ||
|
|
cad2fe1f39 | ||
|
|
b32c5522a2 | ||
|
|
fcd2c15a37 | ||
|
|
421624d3f3 | ||
|
|
ebda0fc538 | ||
|
|
0bddd6efb4 | ||
|
|
cd38677716 |
@@ -7,7 +7,7 @@ package embed
|
|||||||
// client, err := embed.New(embed.Options{
|
// client, err := embed.New(embed.Options{
|
||||||
// DeviceName: "my-service",
|
// DeviceName: "my-service",
|
||||||
// SetupKey: os.Getenv("NB_SETUP_KEY"),
|
// SetupKey: os.Getenv("NB_SETUP_KEY"),
|
||||||
// ManagementURL: os.Getenv("NB_MANAGEMENT_URL"),
|
// managementURL: os.Getenv("NB_MANAGEMENT_URL"),
|
||||||
// })
|
// })
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// log.Fatal(err)
|
// log.Fatal(err)
|
||||||
@@ -41,7 +41,7 @@ package embed
|
|||||||
// client, err := netbird.New(netbird.Options{
|
// client, err := netbird.New(netbird.Options{
|
||||||
// DeviceName: "http-server",
|
// DeviceName: "http-server",
|
||||||
// SetupKey: os.Getenv("NB_SETUP_KEY"),
|
// SetupKey: os.Getenv("NB_SETUP_KEY"),
|
||||||
// ManagementURL: os.Getenv("NB_MANAGEMENT_URL"),
|
// managementURL: os.Getenv("NB_MANAGEMENT_URL"),
|
||||||
// LogOutput: io.Discard,
|
// LogOutput: io.Discard,
|
||||||
// })
|
// })
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
@@ -113,7 +113,7 @@ package embed
|
|||||||
// client, err := netbird.New(netbird.Options{
|
// client, err := netbird.New(netbird.Options{
|
||||||
// DeviceName: "http-client",
|
// DeviceName: "http-client",
|
||||||
// SetupKey: os.Getenv("NB_SETUP_KEY"),
|
// SetupKey: os.Getenv("NB_SETUP_KEY"),
|
||||||
// ManagementURL: os.Getenv("NB_MANAGEMENT_URL"),
|
// managementURL: os.Getenv("NB_MANAGEMENT_URL"),
|
||||||
// LogOutput: io.Discard,
|
// LogOutput: io.Discard,
|
||||||
// })
|
// })
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ type DNSForwarder struct {
|
|||||||
|
|
||||||
dnsServer *dns.Server
|
dnsServer *dns.Server
|
||||||
mux *dns.ServeMux
|
mux *dns.ServeMux
|
||||||
|
tcpServer *dns.Server
|
||||||
|
tcpMux *dns.ServeMux
|
||||||
|
|
||||||
mutex sync.RWMutex
|
mutex sync.RWMutex
|
||||||
fwdEntries []*ForwarderEntry
|
fwdEntries []*ForwarderEntry
|
||||||
@@ -50,22 +52,41 @@ func NewDNSForwarder(listenAddress string, ttl uint32, firewall firewall.Manager
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *DNSForwarder) Listen(entries []*ForwarderEntry) error {
|
func (f *DNSForwarder) Listen(entries []*ForwarderEntry) error {
|
||||||
log.Infof("listen DNS forwarder on address=%s", f.listenAddress)
|
log.Infof("starting DNS forwarder on address=%s", f.listenAddress)
|
||||||
mux := dns.NewServeMux()
|
|
||||||
|
|
||||||
dnsServer := &dns.Server{
|
// UDP server
|
||||||
|
mux := dns.NewServeMux()
|
||||||
|
f.mux = mux
|
||||||
|
f.dnsServer = &dns.Server{
|
||||||
Addr: f.listenAddress,
|
Addr: f.listenAddress,
|
||||||
Net: "udp",
|
Net: "udp",
|
||||||
Handler: mux,
|
Handler: mux,
|
||||||
}
|
}
|
||||||
f.dnsServer = dnsServer
|
// TCP server
|
||||||
f.mux = mux
|
tcpMux := dns.NewServeMux()
|
||||||
|
f.tcpMux = tcpMux
|
||||||
|
f.tcpServer = &dns.Server{
|
||||||
|
Addr: f.listenAddress,
|
||||||
|
Net: "tcp",
|
||||||
|
Handler: tcpMux,
|
||||||
|
}
|
||||||
|
|
||||||
f.UpdateDomains(entries)
|
f.UpdateDomains(entries)
|
||||||
|
|
||||||
return dnsServer.ListenAndServe()
|
errCh := make(chan error, 2)
|
||||||
}
|
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
log.Infof("DNS UDP listener running on %s", f.listenAddress)
|
||||||
|
errCh <- f.dnsServer.ListenAndServe()
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
log.Infof("DNS TCP listener running on %s", f.listenAddress)
|
||||||
|
errCh <- f.tcpServer.ListenAndServe()
|
||||||
|
}()
|
||||||
|
|
||||||
|
// return the first error we get (e.g. bind failure or shutdown)
|
||||||
|
return <-errCh
|
||||||
|
}
|
||||||
func (f *DNSForwarder) UpdateDomains(entries []*ForwarderEntry) {
|
func (f *DNSForwarder) UpdateDomains(entries []*ForwarderEntry) {
|
||||||
f.mutex.Lock()
|
f.mutex.Lock()
|
||||||
defer f.mutex.Unlock()
|
defer f.mutex.Unlock()
|
||||||
@@ -77,31 +98,41 @@ func (f *DNSForwarder) UpdateDomains(entries []*ForwarderEntry) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
oldDomains := filterDomains(f.fwdEntries)
|
oldDomains := filterDomains(f.fwdEntries)
|
||||||
|
|
||||||
for _, d := range oldDomains {
|
for _, d := range oldDomains {
|
||||||
f.mux.HandleRemove(d.PunycodeString())
|
f.mux.HandleRemove(d.PunycodeString())
|
||||||
|
f.tcpMux.HandleRemove(d.PunycodeString())
|
||||||
}
|
}
|
||||||
|
|
||||||
newDomains := filterDomains(entries)
|
newDomains := filterDomains(entries)
|
||||||
for _, d := range newDomains {
|
for _, d := range newDomains {
|
||||||
f.mux.HandleFunc(d.PunycodeString(), f.handleDNSQuery)
|
f.mux.HandleFunc(d.PunycodeString(), f.handleDNSQueryUDP)
|
||||||
|
f.tcpMux.HandleFunc(d.PunycodeString(), f.handleDNSQueryTCP)
|
||||||
}
|
}
|
||||||
|
|
||||||
f.fwdEntries = entries
|
f.fwdEntries = entries
|
||||||
|
|
||||||
log.Debugf("Updated domains from %v to %v", oldDomains, newDomains)
|
log.Debugf("Updated domains from %v to %v", oldDomains, newDomains)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *DNSForwarder) Close(ctx context.Context) error {
|
func (f *DNSForwarder) Close(ctx context.Context) error {
|
||||||
if f.dnsServer == nil {
|
var result *multierror.Error
|
||||||
return nil
|
|
||||||
|
if f.dnsServer != nil {
|
||||||
|
if err := f.dnsServer.ShutdownContext(ctx); err != nil {
|
||||||
|
result = multierror.Append(result, fmt.Errorf("UDP shutdown: %w", err))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return f.dnsServer.ShutdownContext(ctx)
|
if f.tcpServer != nil {
|
||||||
|
if err := f.tcpServer.ShutdownContext(ctx); err != nil {
|
||||||
|
result = multierror.Append(result, fmt.Errorf("TCP shutdown: %w", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nberrors.FormatErrorOrNil(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *DNSForwarder) handleDNSQuery(w dns.ResponseWriter, query *dns.Msg) {
|
func (f *DNSForwarder) handleDNSQuery(w dns.ResponseWriter, query *dns.Msg) *dns.Msg {
|
||||||
if len(query.Question) == 0 {
|
if len(query.Question) == 0 {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
question := query.Question[0]
|
question := query.Question[0]
|
||||||
log.Tracef("received DNS request for DNS forwarder: domain=%v type=%v class=%v",
|
log.Tracef("received DNS request for DNS forwarder: domain=%v type=%v class=%v",
|
||||||
@@ -123,20 +154,53 @@ func (f *DNSForwarder) handleDNSQuery(w dns.ResponseWriter, query *dns.Msg) {
|
|||||||
if err := w.WriteMsg(resp); err != nil {
|
if err := w.WriteMsg(resp); err != nil {
|
||||||
log.Errorf("failed to write DNS response: %v", err)
|
log.Errorf("failed to write DNS response: %v", err)
|
||||||
}
|
}
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), upstreamTimeout)
|
ctx, cancel := context.WithTimeout(context.Background(), upstreamTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
ips, err := net.DefaultResolver.LookupNetIP(ctx, network, domain)
|
ips, err := net.DefaultResolver.LookupNetIP(ctx, network, domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
f.handleDNSError(w, resp, domain, err)
|
f.handleDNSError(w, query, resp, domain, err)
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
f.updateInternalState(domain, ips)
|
f.updateInternalState(domain, ips)
|
||||||
f.addIPsToResponse(resp, domain, ips)
|
f.addIPsToResponse(resp, domain, ips)
|
||||||
|
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *DNSForwarder) handleDNSQueryUDP(w dns.ResponseWriter, query *dns.Msg) {
|
||||||
|
|
||||||
|
resp := f.handleDNSQuery(w, query)
|
||||||
|
if resp == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
opt := query.IsEdns0()
|
||||||
|
maxSize := dns.MinMsgSize
|
||||||
|
if opt != nil {
|
||||||
|
// client advertised a larger EDNS0 buffer
|
||||||
|
maxSize = int(opt.UDPSize())
|
||||||
|
}
|
||||||
|
|
||||||
|
// if our response is too big, truncate and set the TC bit
|
||||||
|
if resp.Len() > maxSize {
|
||||||
|
resp.Truncate(maxSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := w.WriteMsg(resp); err != nil {
|
||||||
|
log.Errorf("failed to write DNS response: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *DNSForwarder) handleDNSQueryTCP(w dns.ResponseWriter, query *dns.Msg) {
|
||||||
|
resp := f.handleDNSQuery(w, query)
|
||||||
|
if resp == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if err := w.WriteMsg(resp); err != nil {
|
if err := w.WriteMsg(resp); err != nil {
|
||||||
log.Errorf("failed to write DNS response: %v", err)
|
log.Errorf("failed to write DNS response: %v", err)
|
||||||
}
|
}
|
||||||
@@ -179,7 +243,7 @@ func (f *DNSForwarder) updateFirewall(matchingEntries []*ForwarderEntry, prefixe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handleDNSError processes DNS lookup errors and sends an appropriate error response
|
// handleDNSError processes DNS lookup errors and sends an appropriate error response
|
||||||
func (f *DNSForwarder) handleDNSError(w dns.ResponseWriter, resp *dns.Msg, domain string, err error) {
|
func (f *DNSForwarder) handleDNSError(w dns.ResponseWriter, query, resp *dns.Msg, domain string, err error) {
|
||||||
var dnsErr *net.DNSError
|
var dnsErr *net.DNSError
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
@@ -191,7 +255,7 @@ func (f *DNSForwarder) handleDNSError(w dns.ResponseWriter, resp *dns.Msg, domai
|
|||||||
}
|
}
|
||||||
|
|
||||||
if dnsErr.Server != "" {
|
if dnsErr.Server != "" {
|
||||||
log.Warnf("failed to resolve query for domain=%s server=%s: %v", domain, dnsErr.Server, err)
|
log.Warnf("failed to resolve query for type=%s domain=%s server=%s: %v", dns.TypeToString[query.Question[0].Qtype], domain, dnsErr.Server, err)
|
||||||
} else {
|
} else {
|
||||||
log.Warnf(errResolveFailed, domain, err)
|
log.Warnf(errResolveFailed, domain, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ type Manager struct {
|
|||||||
statusRecorder *peer.Status
|
statusRecorder *peer.Status
|
||||||
|
|
||||||
fwRules []firewall.Rule
|
fwRules []firewall.Rule
|
||||||
|
tcpRules []firewall.Rule
|
||||||
dnsForwarder *DNSForwarder
|
dnsForwarder *DNSForwarder
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,6 +108,13 @@ func (m *Manager) allowDNSFirewall() error {
|
|||||||
}
|
}
|
||||||
m.fwRules = dnsRules
|
m.fwRules = dnsRules
|
||||||
|
|
||||||
|
tcpRules, err := m.firewall.AddPeerFiltering(nil, net.IP{0, 0, 0, 0}, firewall.ProtocolTCP, nil, dport, firewall.ActionAccept, "")
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to add allow DNS router rules, err: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
m.tcpRules = tcpRules
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +125,13 @@ func (m *Manager) dropDNSFirewall() error {
|
|||||||
mErr = multierror.Append(mErr, fmt.Errorf("failed to delete DNS router rules, err: %v", err))
|
mErr = multierror.Append(mErr, fmt.Errorf("failed to delete DNS router rules, err: %v", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for _, rule := range m.tcpRules {
|
||||||
|
if err := m.firewall.DeletePeerRule(rule); err != nil {
|
||||||
|
mErr = multierror.Append(mErr, fmt.Errorf("failed to delete DNS router rules, err: %v", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m.fwRules = nil
|
m.fwRules = nil
|
||||||
|
m.tcpRules = nil
|
||||||
return nberrors.FormatErrorOrNil(mErr)
|
return nberrors.FormatErrorOrNil(mErr)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import (
|
|||||||
func checkChange(ctx context.Context, nexthopv4, nexthopv6 systemops.Nexthop) error {
|
func checkChange(ctx context.Context, nexthopv4, nexthopv6 systemops.Nexthop) error {
|
||||||
fd, err := unix.Socket(syscall.AF_ROUTE, syscall.SOCK_RAW, syscall.AF_UNSPEC)
|
fd, err := unix.Socket(syscall.AF_ROUTE, syscall.SOCK_RAW, syscall.AF_UNSPEC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to open routing socket: %v", err)
|
return fmt.Errorf("open routing socket: %v", err)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
err := unix.Close(fd)
|
err := unix.Close(fd)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import (
|
|||||||
func checkChange(ctx context.Context, nexthopv4, nexthopv6 systemops.Nexthop) error {
|
func checkChange(ctx context.Context, nexthopv4, nexthopv6 systemops.Nexthop) error {
|
||||||
routeMonitor, err := systemops.NewRouteMonitor(ctx)
|
routeMonitor, err := systemops.NewRouteMonitor(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create route monitor: %w", err)
|
return fmt.Errorf("create route monitor: %w", err)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := routeMonitor.Stop(); err != nil {
|
if err := routeMonitor.Stop(); err != nil {
|
||||||
@@ -38,35 +38,49 @@ func checkChange(ctx context.Context, nexthopv4, nexthopv6 systemops.Nexthop) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
func routeChanged(route systemops.RouteUpdate, nexthopv4, nexthopv6 systemops.Nexthop) bool {
|
func routeChanged(route systemops.RouteUpdate, nexthopv4, nexthopv6 systemops.Nexthop) bool {
|
||||||
intf := "<nil>"
|
if intf := route.NextHop.Intf; intf != nil && isSoftInterface(intf.Name) {
|
||||||
if route.Interface != nil {
|
log.Debugf("Network monitor: ignoring default route change for next hop with soft interface %s", route.NextHop)
|
||||||
intf = route.Interface.Name
|
return false
|
||||||
if isSoftInterface(intf) {
|
}
|
||||||
log.Debugf("Network monitor: ignoring default route change for soft interface %s", intf)
|
|
||||||
return false
|
// TODO: for the empty nexthop ip (on-link), determine the family differently
|
||||||
}
|
nexthop := nexthopv4
|
||||||
|
if route.NextHop.IP.Is6() {
|
||||||
|
nexthop = nexthopv6
|
||||||
}
|
}
|
||||||
|
|
||||||
switch route.Type {
|
switch route.Type {
|
||||||
case systemops.RouteModified:
|
case systemops.RouteModified, systemops.RouteAdded:
|
||||||
// TODO: get routing table to figure out if our route is affected for modified routes
|
return handleRouteAddedOrModified(route, nexthop)
|
||||||
log.Infof("Network monitor: default route changed: via %s, interface %s", route.NextHop, intf)
|
|
||||||
return true
|
|
||||||
case systemops.RouteAdded:
|
|
||||||
if route.NextHop.Is4() && route.NextHop != nexthopv4.IP || route.NextHop.Is6() && route.NextHop != nexthopv6.IP {
|
|
||||||
log.Infof("Network monitor: default route added: via %s, interface %s", route.NextHop, intf)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
case systemops.RouteDeleted:
|
case systemops.RouteDeleted:
|
||||||
if nexthopv4.Intf != nil && route.NextHop == nexthopv4.IP || nexthopv6.Intf != nil && route.NextHop == nexthopv6.IP {
|
return handleRouteDeleted(route, nexthop)
|
||||||
log.Infof("Network monitor: default route removed: via %s, interface %s", route.NextHop, intf)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleRouteAddedOrModified(route systemops.RouteUpdate, nexthop systemops.Nexthop) bool {
|
||||||
|
// For added/modified routes, we care about different next hops
|
||||||
|
if !nexthop.Equal(route.NextHop) {
|
||||||
|
action := "changed"
|
||||||
|
if route.Type == systemops.RouteAdded {
|
||||||
|
action = "added"
|
||||||
|
}
|
||||||
|
log.Infof("Network monitor: default route %s: via %s", action, route.NextHop)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleRouteDeleted(route systemops.RouteUpdate, nexthop systemops.Nexthop) bool {
|
||||||
|
// For deleted routes, we care about our tracked next hop being deleted
|
||||||
|
if nexthop.Equal(route.NextHop) {
|
||||||
|
log.Infof("Network monitor: default route removed: via %s", route.NextHop)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func isSoftInterface(name string) bool {
|
func isSoftInterface(name string) bool {
|
||||||
return strings.Contains(strings.ToLower(name), "isatap") || strings.Contains(strings.ToLower(name), "teredo")
|
return strings.Contains(strings.ToLower(name), "isatap") || strings.Contains(strings.ToLower(name), "teredo")
|
||||||
}
|
}
|
||||||
|
|||||||
404
client/internal/networkmonitor/check_change_windows_test.go
Normal file
404
client/internal/networkmonitor/check_change_windows_test.go
Normal file
@@ -0,0 +1,404 @@
|
|||||||
|
package networkmonitor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"net/netip"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/netbirdio/netbird/client/internal/routemanager/systemops"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRouteChanged(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
route systemops.RouteUpdate
|
||||||
|
nexthopv4 systemops.Nexthop
|
||||||
|
nexthopv6 systemops.Nexthop
|
||||||
|
expected bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "soft interface should be ignored",
|
||||||
|
route: systemops.RouteUpdate{
|
||||||
|
Type: systemops.RouteModified,
|
||||||
|
Destination: netip.PrefixFrom(netip.IPv4Unspecified(), 0),
|
||||||
|
NextHop: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
Intf: &net.Interface{
|
||||||
|
Name: "ISATAP-Interface", // isSoftInterface checks name
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv4: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.2"),
|
||||||
|
},
|
||||||
|
nexthopv6: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::1"),
|
||||||
|
},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "modified route with different v4 nexthop IP should return true",
|
||||||
|
route: systemops.RouteUpdate{
|
||||||
|
Type: systemops.RouteModified,
|
||||||
|
Destination: netip.PrefixFrom(netip.IPv4Unspecified(), 0),
|
||||||
|
NextHop: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
Intf: &net.Interface{
|
||||||
|
Index: 1, Name: "eth0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv4: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.2"),
|
||||||
|
Intf: &net.Interface{
|
||||||
|
Index: 1, Name: "eth0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv6: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::1"),
|
||||||
|
},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "modified route with same v4 nexthop (IP and Intf Index) should return false",
|
||||||
|
route: systemops.RouteUpdate{
|
||||||
|
Type: systemops.RouteModified,
|
||||||
|
Destination: netip.PrefixFrom(netip.IPv4Unspecified(), 0),
|
||||||
|
NextHop: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
Intf: &net.Interface{
|
||||||
|
Index: 1, Name: "eth0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv4: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
Intf: &net.Interface{
|
||||||
|
Index: 1, Name: "eth0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv6: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::1"),
|
||||||
|
},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "added route with different v6 nexthop IP should return true",
|
||||||
|
route: systemops.RouteUpdate{
|
||||||
|
Type: systemops.RouteAdded,
|
||||||
|
Destination: netip.PrefixFrom(netip.IPv6Unspecified(), 0),
|
||||||
|
NextHop: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::2"),
|
||||||
|
Intf: &net.Interface{
|
||||||
|
Index: 1, Name: "eth0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv4: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
},
|
||||||
|
nexthopv6: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::1"),
|
||||||
|
Intf: &net.Interface{
|
||||||
|
Index: 1, Name: "eth0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "added route with same v6 nexthop (IP and Intf Index) should return false",
|
||||||
|
route: systemops.RouteUpdate{
|
||||||
|
Type: systemops.RouteAdded,
|
||||||
|
Destination: netip.PrefixFrom(netip.IPv6Unspecified(), 0),
|
||||||
|
NextHop: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::1"),
|
||||||
|
Intf: &net.Interface{
|
||||||
|
Index: 1, Name: "eth0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv4: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
},
|
||||||
|
nexthopv6: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::1"),
|
||||||
|
Intf: &net.Interface{
|
||||||
|
Index: 1, Name: "eth0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "deleted route matching tracked v4 nexthop (IP and Intf Index) should return true",
|
||||||
|
route: systemops.RouteUpdate{
|
||||||
|
Type: systemops.RouteDeleted,
|
||||||
|
Destination: netip.PrefixFrom(netip.IPv4Unspecified(), 0),
|
||||||
|
NextHop: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
Intf: &net.Interface{
|
||||||
|
Index: 1, Name: "eth0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv4: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
Intf: &net.Interface{
|
||||||
|
Index: 1, Name: "eth0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv6: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::1"),
|
||||||
|
},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "deleted route not matching tracked v4 nexthop (different IP) should return false",
|
||||||
|
route: systemops.RouteUpdate{
|
||||||
|
Type: systemops.RouteDeleted,
|
||||||
|
Destination: netip.PrefixFrom(netip.IPv4Unspecified(), 0),
|
||||||
|
NextHop: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.3"), // Different IP
|
||||||
|
Intf: &net.Interface{
|
||||||
|
Index: 1, Name: "eth0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv4: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
Intf: &net.Interface{
|
||||||
|
Index: 1, Name: "eth0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv6: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::1"),
|
||||||
|
},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "modified v4 route with same IP, different Intf Index should return true",
|
||||||
|
route: systemops.RouteUpdate{
|
||||||
|
Type: systemops.RouteModified,
|
||||||
|
Destination: netip.PrefixFrom(netip.IPv4Unspecified(), 0),
|
||||||
|
NextHop: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
Intf: &net.Interface{Index: 2, Name: "eth1"}, // Different Intf Index
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv4: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
Intf: &net.Interface{Index: 1, Name: "eth0"},
|
||||||
|
},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "modified v4 route with same IP, one Intf nil, other non-nil should return true",
|
||||||
|
route: systemops.RouteUpdate{
|
||||||
|
Type: systemops.RouteModified,
|
||||||
|
Destination: netip.PrefixFrom(netip.IPv4Unspecified(), 0),
|
||||||
|
NextHop: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
Intf: nil, // Intf is nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv4: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
Intf: &net.Interface{Index: 1, Name: "eth0"}, // Tracked Intf is not nil
|
||||||
|
},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "added v4 route with same IP, different Intf Index should return true",
|
||||||
|
route: systemops.RouteUpdate{
|
||||||
|
Type: systemops.RouteAdded,
|
||||||
|
Destination: netip.PrefixFrom(netip.IPv4Unspecified(), 0),
|
||||||
|
NextHop: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
Intf: &net.Interface{Index: 2, Name: "eth1"}, // Different Intf Index
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv4: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
Intf: &net.Interface{Index: 1, Name: "eth0"},
|
||||||
|
},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "deleted v4 route with same IP, different Intf Index should return false",
|
||||||
|
route: systemops.RouteUpdate{
|
||||||
|
Type: systemops.RouteDeleted,
|
||||||
|
Destination: netip.PrefixFrom(netip.IPv4Unspecified(), 0),
|
||||||
|
NextHop: systemops.Nexthop{ // This is the route being deleted
|
||||||
|
IP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
Intf: &net.Interface{Index: 1, Name: "eth0"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv4: systemops.Nexthop{ // This is our tracked nexthop
|
||||||
|
IP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
Intf: &net.Interface{Index: 2, Name: "eth1"}, // Different Intf Index
|
||||||
|
},
|
||||||
|
expected: false, // Because nexthopv4.Equal(route.NextHop) will be false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "modified v6 route with different IP, same Intf Index should return true",
|
||||||
|
route: systemops.RouteUpdate{
|
||||||
|
Type: systemops.RouteModified,
|
||||||
|
Destination: netip.PrefixFrom(netip.IPv6Unspecified(), 0),
|
||||||
|
NextHop: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::3"), // Different IP
|
||||||
|
Intf: &net.Interface{Index: 1, Name: "eth0"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv6: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::1"),
|
||||||
|
Intf: &net.Interface{Index: 1, Name: "eth0"},
|
||||||
|
},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "modified v6 route with same IP, different Intf Index should return true",
|
||||||
|
route: systemops.RouteUpdate{
|
||||||
|
Type: systemops.RouteModified,
|
||||||
|
Destination: netip.PrefixFrom(netip.IPv6Unspecified(), 0),
|
||||||
|
NextHop: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::1"),
|
||||||
|
Intf: &net.Interface{Index: 2, Name: "eth1"}, // Different Intf Index
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv6: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::1"),
|
||||||
|
Intf: &net.Interface{Index: 1, Name: "eth0"},
|
||||||
|
},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "modified v6 route with same IP, same Intf Index should return false",
|
||||||
|
route: systemops.RouteUpdate{
|
||||||
|
Type: systemops.RouteModified,
|
||||||
|
Destination: netip.PrefixFrom(netip.IPv6Unspecified(), 0),
|
||||||
|
NextHop: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::1"),
|
||||||
|
Intf: &net.Interface{Index: 1, Name: "eth0"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv6: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::1"),
|
||||||
|
Intf: &net.Interface{Index: 1, Name: "eth0"},
|
||||||
|
},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "deleted v6 route matching tracked nexthop (IP and Intf Index) should return true",
|
||||||
|
route: systemops.RouteUpdate{
|
||||||
|
Type: systemops.RouteDeleted,
|
||||||
|
Destination: netip.PrefixFrom(netip.IPv6Unspecified(), 0),
|
||||||
|
NextHop: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::1"),
|
||||||
|
Intf: &net.Interface{Index: 1, Name: "eth0"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv6: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::1"),
|
||||||
|
Intf: &net.Interface{Index: 1, Name: "eth0"},
|
||||||
|
},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "deleted v6 route not matching tracked nexthop (different IP) should return false",
|
||||||
|
route: systemops.RouteUpdate{
|
||||||
|
Type: systemops.RouteDeleted,
|
||||||
|
Destination: netip.PrefixFrom(netip.IPv6Unspecified(), 0),
|
||||||
|
NextHop: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::3"), // Different IP
|
||||||
|
Intf: &net.Interface{Index: 1, Name: "eth0"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv6: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("2001:db8::1"),
|
||||||
|
Intf: &net.Interface{Index: 1, Name: "eth0"},
|
||||||
|
},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "deleted v6 route not matching tracked nexthop (same IP, different Intf Index) should return false",
|
||||||
|
route: systemops.RouteUpdate{
|
||||||
|
Type: systemops.RouteDeleted,
|
||||||
|
Destination: netip.PrefixFrom(netip.IPv6Unspecified(), 0),
|
||||||
|
NextHop: systemops.Nexthop{ // This is the route being deleted
|
||||||
|
IP: netip.MustParseAddr("2001:db8::1"),
|
||||||
|
Intf: &net.Interface{Index: 1, Name: "eth0"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv6: systemops.Nexthop{ // This is our tracked nexthop
|
||||||
|
IP: netip.MustParseAddr("2001:db8::1"),
|
||||||
|
Intf: &net.Interface{Index: 2, Name: "eth1"}, // Different Intf Index
|
||||||
|
},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unknown route type should return false",
|
||||||
|
route: systemops.RouteUpdate{
|
||||||
|
Type: systemops.RouteUpdateType(99), // Unknown type
|
||||||
|
Destination: netip.PrefixFrom(netip.IPv4Unspecified(), 0),
|
||||||
|
NextHop: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
Intf: &net.Interface{Index: 1, Name: "eth0"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nexthopv4: systemops.Nexthop{
|
||||||
|
IP: netip.MustParseAddr("192.168.1.2"), // Different from route.NextHop
|
||||||
|
Intf: &net.Interface{Index: 1, Name: "eth0"},
|
||||||
|
},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := routeChanged(tt.route, tt.nexthopv4, tt.nexthopv6)
|
||||||
|
assert.Equal(t, tt.expected, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsSoftInterface(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
ifname string
|
||||||
|
expected bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "ISATAP interface should be detected",
|
||||||
|
ifname: "ISATAP tunnel adapter",
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lowercase soft interface should be detected",
|
||||||
|
ifname: "isatap.{14A5CF17-CA72-43EC-B4EA-B4B093641B7D}",
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Teredo interface should be detected",
|
||||||
|
ifname: "Teredo Tunneling Pseudo-Interface",
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "regular interface should not be detected as soft",
|
||||||
|
ifname: "eth0",
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "another regular interface should not be detected as soft",
|
||||||
|
ifname: "wlan0",
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := isSoftInterface(tt.ifname)
|
||||||
|
assert.Equal(t, tt.expected, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -118,9 +118,12 @@ func (nw *NetworkMonitor) Stop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (nw *NetworkMonitor) checkChanges(ctx context.Context, event chan struct{}, nexthop4 systemops.Nexthop, nexthop6 systemops.Nexthop) {
|
func (nw *NetworkMonitor) checkChanges(ctx context.Context, event chan struct{}, nexthop4 systemops.Nexthop, nexthop6 systemops.Nexthop) {
|
||||||
|
defer close(event)
|
||||||
for {
|
for {
|
||||||
if err := checkChangeFn(ctx, nexthop4, nexthop6); err != nil {
|
if err := checkChangeFn(ctx, nexthop4, nexthop6); err != nil {
|
||||||
close(event)
|
if !errors.Is(err, context.Canceled) {
|
||||||
|
log.Errorf("Network monitor: failed to check for changes: %v", err)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// prevent blocking
|
// prevent blocking
|
||||||
|
|||||||
@@ -32,6 +32,10 @@ func (n *Notifier) SetListener(listener listener.NetworkChangeListener) {
|
|||||||
func (n *Notifier) SetInitialClientRoutes(clientRoutes []*route.Route) {
|
func (n *Notifier) SetInitialClientRoutes(clientRoutes []*route.Route) {
|
||||||
nets := make([]string, 0)
|
nets := make([]string, 0)
|
||||||
for _, r := range clientRoutes {
|
for _, r := range clientRoutes {
|
||||||
|
// filter out domain routes
|
||||||
|
if r.IsDynamic() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
nets = append(nets, r.Network.String())
|
nets = append(nets, r.Network.String())
|
||||||
}
|
}
|
||||||
sort.Strings(nets)
|
sort.Strings(nets)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package systemops
|
package systemops
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -15,6 +16,20 @@ type Nexthop struct {
|
|||||||
Intf *net.Interface
|
Intf *net.Interface
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Equal checks if two nexthops are equal.
|
||||||
|
func (n Nexthop) Equal(other Nexthop) bool {
|
||||||
|
return n.IP == other.IP && (n.Intf == nil && other.Intf == nil ||
|
||||||
|
n.Intf != nil && other.Intf != nil && n.Intf.Index == other.Intf.Index)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns a string representation of the nexthop.
|
||||||
|
func (n Nexthop) String() string {
|
||||||
|
if n.Intf == nil {
|
||||||
|
return n.IP.String()
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s @ %d (%s)", n.IP.String(), n.Intf.Index, n.Intf.Name)
|
||||||
|
}
|
||||||
|
|
||||||
type ExclusionCounter = refcounter.Counter[netip.Prefix, struct{}, Nexthop]
|
type ExclusionCounter = refcounter.Counter[netip.Prefix, struct{}, Nexthop]
|
||||||
|
|
||||||
type SysOps struct {
|
type SysOps struct {
|
||||||
|
|||||||
@@ -33,8 +33,7 @@ type RouteUpdateType int
|
|||||||
type RouteUpdate struct {
|
type RouteUpdate struct {
|
||||||
Type RouteUpdateType
|
Type RouteUpdateType
|
||||||
Destination netip.Prefix
|
Destination netip.Prefix
|
||||||
NextHop netip.Addr
|
NextHop Nexthop
|
||||||
Interface *net.Interface
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RouteMonitor provides a way to monitor changes in the routing table.
|
// RouteMonitor provides a way to monitor changes in the routing table.
|
||||||
@@ -231,15 +230,15 @@ func (rm *RouteMonitor) parseUpdate(row *MIB_IPFORWARD_ROW2, notificationType MI
|
|||||||
intf, err := net.InterfaceByIndex(idx)
|
intf, err := net.InterfaceByIndex(idx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("failed to get interface name for index %d: %v", idx, err)
|
log.Warnf("failed to get interface name for index %d: %v", idx, err)
|
||||||
update.Interface = &net.Interface{
|
update.NextHop.Intf = &net.Interface{
|
||||||
Index: idx,
|
Index: idx,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
update.Interface = intf
|
update.NextHop.Intf = intf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Tracef("Received route update with destination %v, next hop %v, interface %v", row.DestinationPrefix, row.NextHop, update.Interface)
|
log.Tracef("Received route update with destination %v, next hop %v, interface %v", row.DestinationPrefix, row.NextHop, update.NextHop.Intf)
|
||||||
dest := parseIPPrefix(row.DestinationPrefix, idx)
|
dest := parseIPPrefix(row.DestinationPrefix, idx)
|
||||||
if !dest.Addr().IsValid() {
|
if !dest.Addr().IsValid() {
|
||||||
return RouteUpdate{}, fmt.Errorf("invalid destination: %v", row)
|
return RouteUpdate{}, fmt.Errorf("invalid destination: %v", row)
|
||||||
@@ -262,7 +261,7 @@ func (rm *RouteMonitor) parseUpdate(row *MIB_IPFORWARD_ROW2, notificationType MI
|
|||||||
|
|
||||||
update.Type = updateType
|
update.Type = updateType
|
||||||
update.Destination = dest
|
update.Destination = dest
|
||||||
update.NextHop = nexthop
|
update.NextHop.IP = nexthop
|
||||||
|
|
||||||
return update, nil
|
return update, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type AccountsAPI struct {
|
|||||||
// List list all accounts, only returns one account always
|
// List list all accounts, only returns one account always
|
||||||
// See more: https://docs.netbird.io/api/resources/accounts#list-all-accounts
|
// See more: https://docs.netbird.io/api/resources/accounts#list-all-accounts
|
||||||
func (a *AccountsAPI) List(ctx context.Context) ([]api.Account, error) {
|
func (a *AccountsAPI) List(ctx context.Context) ([]api.Account, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/accounts", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/accounts", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ func (a *AccountsAPI) Update(ctx context.Context, accountID string, request api.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/accounts/"+accountID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/accounts/"+accountID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (a *AccountsAPI) Update(ctx context.Context, accountID string, request api.
|
|||||||
// Delete delete account
|
// Delete delete account
|
||||||
// See more: https://docs.netbird.io/api/resources/accounts#delete-an-account
|
// See more: https://docs.netbird.io/api/resources/accounts#delete-an-account
|
||||||
func (a *AccountsAPI) Delete(ctx context.Context, accountID string) error {
|
func (a *AccountsAPI) Delete(ctx context.Context, accountID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/accounts/"+accountID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/accounts/"+accountID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
type Client struct {
|
type Client struct {
|
||||||
managementURL string
|
managementURL string
|
||||||
authHeader string
|
authHeader string
|
||||||
|
httpClient HttpClient
|
||||||
|
|
||||||
// Accounts NetBird account APIs
|
// Accounts NetBird account APIs
|
||||||
// see more: https://docs.netbird.io/api/resources/accounts
|
// see more: https://docs.netbird.io/api/resources/accounts
|
||||||
@@ -70,20 +71,29 @@ type Client struct {
|
|||||||
|
|
||||||
// New initialize new Client instance using PAT token
|
// New initialize new Client instance using PAT token
|
||||||
func New(managementURL, token string) *Client {
|
func New(managementURL, token string) *Client {
|
||||||
client := &Client{
|
return NewWithOptions(
|
||||||
managementURL: managementURL,
|
WithManagementURL(managementURL),
|
||||||
authHeader: "Token " + token,
|
WithPAT(token),
|
||||||
}
|
)
|
||||||
client.initialize()
|
|
||||||
return client
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewWithBearerToken initialize new Client instance using Bearer token type
|
// NewWithBearerToken initialize new Client instance using Bearer token type
|
||||||
func NewWithBearerToken(managementURL, token string) *Client {
|
func NewWithBearerToken(managementURL, token string) *Client {
|
||||||
|
return NewWithOptions(
|
||||||
|
WithManagementURL(managementURL),
|
||||||
|
WithBearerToken(token),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWithOptions(opts ...option) *Client {
|
||||||
client := &Client{
|
client := &Client{
|
||||||
managementURL: managementURL,
|
httpClient: http.DefaultClient,
|
||||||
authHeader: "Bearer " + token,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, option := range opts {
|
||||||
|
option(client)
|
||||||
|
}
|
||||||
|
|
||||||
client.initialize()
|
client.initialize()
|
||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
@@ -104,7 +114,7 @@ func (c *Client) initialize() {
|
|||||||
c.Events = &EventsAPI{c}
|
c.Events = &EventsAPI{c}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) newRequest(ctx context.Context, method, path string, body io.Reader) (*http.Response, error) {
|
func (c *Client) NewRequest(ctx context.Context, method, path string, body io.Reader) (*http.Response, error) {
|
||||||
req, err := http.NewRequestWithContext(ctx, method, c.managementURL+path, body)
|
req, err := http.NewRequestWithContext(ctx, method, c.managementURL+path, body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -116,7 +126,7 @@ func (c *Client) newRequest(ctx context.Context, method, path string, body io.Re
|
|||||||
req.Header.Add("Content-Type", "application/json")
|
req.Header.Add("Content-Type", "application/json")
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := c.httpClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type DNSAPI struct {
|
|||||||
// ListNameserverGroups list all nameserver groups
|
// ListNameserverGroups list all nameserver groups
|
||||||
// See more: https://docs.netbird.io/api/resources/dns#list-all-nameserver-groups
|
// See more: https://docs.netbird.io/api/resources/dns#list-all-nameserver-groups
|
||||||
func (a *DNSAPI) ListNameserverGroups(ctx context.Context) ([]api.NameserverGroup, error) {
|
func (a *DNSAPI) ListNameserverGroups(ctx context.Context) ([]api.NameserverGroup, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/dns/nameservers", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/dns/nameservers", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ func (a *DNSAPI) ListNameserverGroups(ctx context.Context) ([]api.NameserverGrou
|
|||||||
// GetNameserverGroup get nameserver group info
|
// GetNameserverGroup get nameserver group info
|
||||||
// See more: https://docs.netbird.io/api/resources/dns#retrieve-a-nameserver-group
|
// See more: https://docs.netbird.io/api/resources/dns#retrieve-a-nameserver-group
|
||||||
func (a *DNSAPI) GetNameserverGroup(ctx context.Context, nameserverGroupID string) (*api.NameserverGroup, error) {
|
func (a *DNSAPI) GetNameserverGroup(ctx context.Context, nameserverGroupID string) (*api.NameserverGroup, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/dns/nameservers/"+nameserverGroupID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/dns/nameservers/"+nameserverGroupID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (a *DNSAPI) CreateNameserverGroup(ctx context.Context, request api.PostApiD
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/dns/nameservers", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/dns/nameservers", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ func (a *DNSAPI) UpdateNameserverGroup(ctx context.Context, nameserverGroupID st
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/dns/nameservers/"+nameserverGroupID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/dns/nameservers/"+nameserverGroupID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ func (a *DNSAPI) UpdateNameserverGroup(ctx context.Context, nameserverGroupID st
|
|||||||
// DeleteNameserverGroup delete nameserver group
|
// DeleteNameserverGroup delete nameserver group
|
||||||
// See more: https://docs.netbird.io/api/resources/dns#delete-a-nameserver-group
|
// See more: https://docs.netbird.io/api/resources/dns#delete-a-nameserver-group
|
||||||
func (a *DNSAPI) DeleteNameserverGroup(ctx context.Context, nameserverGroupID string) error {
|
func (a *DNSAPI) DeleteNameserverGroup(ctx context.Context, nameserverGroupID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/dns/nameservers/"+nameserverGroupID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/dns/nameservers/"+nameserverGroupID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ func (a *DNSAPI) DeleteNameserverGroup(ctx context.Context, nameserverGroupID st
|
|||||||
// GetSettings get DNS settings
|
// GetSettings get DNS settings
|
||||||
// See more: https://docs.netbird.io/api/resources/dns#retrieve-dns-settings
|
// See more: https://docs.netbird.io/api/resources/dns#retrieve-dns-settings
|
||||||
func (a *DNSAPI) GetSettings(ctx context.Context) (*api.DNSSettings, error) {
|
func (a *DNSAPI) GetSettings(ctx context.Context) (*api.DNSSettings, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/dns/settings", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/dns/settings", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -112,7 +112,7 @@ func (a *DNSAPI) UpdateSettings(ctx context.Context, request api.PutApiDnsSettin
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/dns/settings", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/dns/settings", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ type EventsAPI struct {
|
|||||||
// List list all events
|
// List list all events
|
||||||
// See more: https://docs.netbird.io/api/resources/events#list-all-events
|
// See more: https://docs.netbird.io/api/resources/events#list-all-events
|
||||||
func (a *EventsAPI) List(ctx context.Context) ([]api.Event, error) {
|
func (a *EventsAPI) List(ctx context.Context) ([]api.Event, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/events", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/events", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ type GeoLocationAPI struct {
|
|||||||
// ListCountries list all country codes
|
// ListCountries list all country codes
|
||||||
// See more: https://docs.netbird.io/api/resources/geo-locations#list-all-country-codes
|
// See more: https://docs.netbird.io/api/resources/geo-locations#list-all-country-codes
|
||||||
func (a *GeoLocationAPI) ListCountries(ctx context.Context) ([]api.Country, error) {
|
func (a *GeoLocationAPI) ListCountries(ctx context.Context) ([]api.Country, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/locations/countries", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/locations/countries", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ func (a *GeoLocationAPI) ListCountries(ctx context.Context) ([]api.Country, erro
|
|||||||
// ListCountryCities Get a list of all English city names for a given country code
|
// ListCountryCities Get a list of all English city names for a given country code
|
||||||
// See more: https://docs.netbird.io/api/resources/geo-locations#list-all-city-names-by-country
|
// See more: https://docs.netbird.io/api/resources/geo-locations#list-all-city-names-by-country
|
||||||
func (a *GeoLocationAPI) ListCountryCities(ctx context.Context, countryCode string) ([]api.City, error) {
|
func (a *GeoLocationAPI) ListCountryCities(ctx context.Context, countryCode string) ([]api.City, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/locations/countries/"+countryCode+"/cities", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/locations/countries/"+countryCode+"/cities", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type GroupsAPI struct {
|
|||||||
// List list all groups
|
// List list all groups
|
||||||
// See more: https://docs.netbird.io/api/resources/groups#list-all-groups
|
// See more: https://docs.netbird.io/api/resources/groups#list-all-groups
|
||||||
func (a *GroupsAPI) List(ctx context.Context) ([]api.Group, error) {
|
func (a *GroupsAPI) List(ctx context.Context) ([]api.Group, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/groups", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/groups", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ func (a *GroupsAPI) List(ctx context.Context) ([]api.Group, error) {
|
|||||||
// Get get group info
|
// Get get group info
|
||||||
// See more: https://docs.netbird.io/api/resources/groups#retrieve-a-group
|
// See more: https://docs.netbird.io/api/resources/groups#retrieve-a-group
|
||||||
func (a *GroupsAPI) Get(ctx context.Context, groupID string) (*api.Group, error) {
|
func (a *GroupsAPI) Get(ctx context.Context, groupID string) (*api.Group, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/groups/"+groupID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/groups/"+groupID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (a *GroupsAPI) Create(ctx context.Context, request api.PostApiGroupsJSONReq
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/groups", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/groups", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ func (a *GroupsAPI) Update(ctx context.Context, groupID string, request api.PutA
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/groups/"+groupID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/groups/"+groupID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ func (a *GroupsAPI) Update(ctx context.Context, groupID string, request api.PutA
|
|||||||
// Delete delete group
|
// Delete delete group
|
||||||
// See more: https://docs.netbird.io/api/resources/groups#delete-a-group
|
// See more: https://docs.netbird.io/api/resources/groups#delete-a-group
|
||||||
func (a *GroupsAPI) Delete(ctx context.Context, groupID string) error {
|
func (a *GroupsAPI) Delete(ctx context.Context, groupID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/groups/"+groupID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/groups/"+groupID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type NetworksAPI struct {
|
|||||||
// List list all networks
|
// List list all networks
|
||||||
// See more: https://docs.netbird.io/api/resources/networks#list-all-networks
|
// See more: https://docs.netbird.io/api/resources/networks#list-all-networks
|
||||||
func (a *NetworksAPI) List(ctx context.Context) ([]api.Network, error) {
|
func (a *NetworksAPI) List(ctx context.Context) ([]api.Network, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/networks", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/networks", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ func (a *NetworksAPI) List(ctx context.Context) ([]api.Network, error) {
|
|||||||
// Get get network info
|
// Get get network info
|
||||||
// See more: https://docs.netbird.io/api/resources/networks#retrieve-a-network
|
// See more: https://docs.netbird.io/api/resources/networks#retrieve-a-network
|
||||||
func (a *NetworksAPI) Get(ctx context.Context, networkID string) (*api.Network, error) {
|
func (a *NetworksAPI) Get(ctx context.Context, networkID string) (*api.Network, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/networks/"+networkID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/networks/"+networkID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (a *NetworksAPI) Create(ctx context.Context, request api.PostApiNetworksJSO
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/networks", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/networks", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ func (a *NetworksAPI) Update(ctx context.Context, networkID string, request api.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/networks/"+networkID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/networks/"+networkID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ func (a *NetworksAPI) Update(ctx context.Context, networkID string, request api.
|
|||||||
// Delete delete network
|
// Delete delete network
|
||||||
// See more: https://docs.netbird.io/api/resources/networks#delete-a-network
|
// See more: https://docs.netbird.io/api/resources/networks#delete-a-network
|
||||||
func (a *NetworksAPI) Delete(ctx context.Context, networkID string) error {
|
func (a *NetworksAPI) Delete(ctx context.Context, networkID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/networks/"+networkID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/networks/"+networkID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@ func (a *NetworksAPI) Resources(networkID string) *NetworkResourcesAPI {
|
|||||||
// List list all resources in networks
|
// List list all resources in networks
|
||||||
// See more: https://docs.netbird.io/api/resources/networks#list-all-network-resources
|
// See more: https://docs.netbird.io/api/resources/networks#list-all-network-resources
|
||||||
func (a *NetworkResourcesAPI) List(ctx context.Context) ([]api.NetworkResource, error) {
|
func (a *NetworkResourcesAPI) List(ctx context.Context) ([]api.NetworkResource, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/networks/"+a.networkID+"/resources", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/networks/"+a.networkID+"/resources", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ func (a *NetworkResourcesAPI) List(ctx context.Context) ([]api.NetworkResource,
|
|||||||
// Get get network resource info
|
// Get get network resource info
|
||||||
// See more: https://docs.netbird.io/api/resources/networks#retrieve-a-network-resource
|
// See more: https://docs.netbird.io/api/resources/networks#retrieve-a-network-resource
|
||||||
func (a *NetworkResourcesAPI) Get(ctx context.Context, networkResourceID string) (*api.NetworkResource, error) {
|
func (a *NetworkResourcesAPI) Get(ctx context.Context, networkResourceID string) (*api.NetworkResource, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/networks/"+a.networkID+"/resources/"+networkResourceID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/networks/"+a.networkID+"/resources/"+networkResourceID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,7 @@ func (a *NetworkResourcesAPI) Create(ctx context.Context, request api.PostApiNet
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/networks/"+a.networkID+"/resources", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/networks/"+a.networkID+"/resources", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -158,7 +158,7 @@ func (a *NetworkResourcesAPI) Update(ctx context.Context, networkResourceID stri
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/networks/"+a.networkID+"/resources/"+networkResourceID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/networks/"+a.networkID+"/resources/"+networkResourceID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -172,7 +172,7 @@ func (a *NetworkResourcesAPI) Update(ctx context.Context, networkResourceID stri
|
|||||||
// Delete delete network resource
|
// Delete delete network resource
|
||||||
// See more: https://docs.netbird.io/api/resources/networks#delete-a-network-resource
|
// See more: https://docs.netbird.io/api/resources/networks#delete-a-network-resource
|
||||||
func (a *NetworkResourcesAPI) Delete(ctx context.Context, networkResourceID string) error {
|
func (a *NetworkResourcesAPI) Delete(ctx context.Context, networkResourceID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/networks/"+a.networkID+"/resources/"+networkResourceID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/networks/"+a.networkID+"/resources/"+networkResourceID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -200,7 +200,7 @@ func (a *NetworksAPI) Routers(networkID string) *NetworkRoutersAPI {
|
|||||||
// List list all routers in networks
|
// List list all routers in networks
|
||||||
// See more: https://docs.netbird.io/api/routers/networks#list-all-network-routers
|
// See more: https://docs.netbird.io/api/routers/networks#list-all-network-routers
|
||||||
func (a *NetworkRoutersAPI) List(ctx context.Context) ([]api.NetworkRouter, error) {
|
func (a *NetworkRoutersAPI) List(ctx context.Context) ([]api.NetworkRouter, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/networks/"+a.networkID+"/routers", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/networks/"+a.networkID+"/routers", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -214,7 +214,7 @@ func (a *NetworkRoutersAPI) List(ctx context.Context) ([]api.NetworkRouter, erro
|
|||||||
// Get get network router info
|
// Get get network router info
|
||||||
// See more: https://docs.netbird.io/api/routers/networks#retrieve-a-network-router
|
// See more: https://docs.netbird.io/api/routers/networks#retrieve-a-network-router
|
||||||
func (a *NetworkRoutersAPI) Get(ctx context.Context, networkRouterID string) (*api.NetworkRouter, error) {
|
func (a *NetworkRoutersAPI) Get(ctx context.Context, networkRouterID string) (*api.NetworkRouter, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/networks/"+a.networkID+"/routers/"+networkRouterID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/networks/"+a.networkID+"/routers/"+networkRouterID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -232,7 +232,7 @@ func (a *NetworkRoutersAPI) Create(ctx context.Context, request api.PostApiNetwo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/networks/"+a.networkID+"/routers", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/networks/"+a.networkID+"/routers", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -250,7 +250,7 @@ func (a *NetworkRoutersAPI) Update(ctx context.Context, networkRouterID string,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/networks/"+a.networkID+"/routers/"+networkRouterID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/networks/"+a.networkID+"/routers/"+networkRouterID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -264,7 +264,7 @@ func (a *NetworkRoutersAPI) Update(ctx context.Context, networkRouterID string,
|
|||||||
// Delete delete network router
|
// Delete delete network router
|
||||||
// See more: https://docs.netbird.io/api/routers/networks#delete-a-network-router
|
// See more: https://docs.netbird.io/api/routers/networks#delete-a-network-router
|
||||||
func (a *NetworkRoutersAPI) Delete(ctx context.Context, networkRouterID string) error {
|
func (a *NetworkRoutersAPI) Delete(ctx context.Context, networkRouterID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/networks/"+a.networkID+"/routers/"+networkRouterID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/networks/"+a.networkID+"/routers/"+networkRouterID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
35
management/client/rest/options.go
Normal file
35
management/client/rest/options.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package rest
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
|
type option func(*Client)
|
||||||
|
|
||||||
|
type HttpClient interface {
|
||||||
|
Do(req *http.Request) (*http.Response, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithHttpClient(client HttpClient) option {
|
||||||
|
return func(c *Client) {
|
||||||
|
c.httpClient = client
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithBearerToken(token string) option {
|
||||||
|
return WithAuthHeader("Bearer " + token)
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithPAT(token string) option {
|
||||||
|
return WithAuthHeader("Token " + token)
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithManagementURL(url string) option {
|
||||||
|
return func(c *Client) {
|
||||||
|
c.managementURL = url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithAuthHeader(value string) option {
|
||||||
|
return func(c *Client) {
|
||||||
|
c.authHeader = value
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ type PeersAPI struct {
|
|||||||
// List list all peers
|
// List list all peers
|
||||||
// See more: https://docs.netbird.io/api/resources/peers#list-all-peers
|
// See more: https://docs.netbird.io/api/resources/peers#list-all-peers
|
||||||
func (a *PeersAPI) List(ctx context.Context) ([]api.Peer, error) {
|
func (a *PeersAPI) List(ctx context.Context) ([]api.Peer, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/peers", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/peers", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ func (a *PeersAPI) List(ctx context.Context) ([]api.Peer, error) {
|
|||||||
// Get retrieve a peer
|
// Get retrieve a peer
|
||||||
// See more: https://docs.netbird.io/api/resources/peers#retrieve-a-peer
|
// See more: https://docs.netbird.io/api/resources/peers#retrieve-a-peer
|
||||||
func (a *PeersAPI) Get(ctx context.Context, peerID string) (*api.Peer, error) {
|
func (a *PeersAPI) Get(ctx context.Context, peerID string) (*api.Peer, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/peers/"+peerID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/peers/"+peerID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (a *PeersAPI) Update(ctx context.Context, peerID string, request api.PutApi
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/peers/"+peerID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/peers/"+peerID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ func (a *PeersAPI) Update(ctx context.Context, peerID string, request api.PutApi
|
|||||||
// Delete delete a peer
|
// Delete delete a peer
|
||||||
// See more: https://docs.netbird.io/api/resources/peers#delete-a-peer
|
// See more: https://docs.netbird.io/api/resources/peers#delete-a-peer
|
||||||
func (a *PeersAPI) Delete(ctx context.Context, peerID string) error {
|
func (a *PeersAPI) Delete(ctx context.Context, peerID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/peers/"+peerID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/peers/"+peerID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ func (a *PeersAPI) Delete(ctx context.Context, peerID string) error {
|
|||||||
// ListAccessiblePeers list all peers that the specified peer can connect to within the network
|
// ListAccessiblePeers list all peers that the specified peer can connect to within the network
|
||||||
// See more: https://docs.netbird.io/api/resources/peers#list-accessible-peers
|
// See more: https://docs.netbird.io/api/resources/peers#list-accessible-peers
|
||||||
func (a *PeersAPI) ListAccessiblePeers(ctx context.Context, peerID string) ([]api.Peer, error) {
|
func (a *PeersAPI) ListAccessiblePeers(ctx context.Context, peerID string) ([]api.Peer, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/peers/"+peerID+"/accessible-peers", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/peers/"+peerID+"/accessible-peers", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ type PoliciesAPI struct {
|
|||||||
// List list all policies
|
// List list all policies
|
||||||
// See more: https://docs.netbird.io/api/resources/policies#list-all-policies
|
// See more: https://docs.netbird.io/api/resources/policies#list-all-policies
|
||||||
func (a *PoliciesAPI) List(ctx context.Context) ([]api.Policy, error) {
|
func (a *PoliciesAPI) List(ctx context.Context) ([]api.Policy, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/policies", nil)
|
path := "/api/policies"
|
||||||
|
|
||||||
|
resp, err := a.c.NewRequest(ctx, "GET", path, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +32,7 @@ func (a *PoliciesAPI) List(ctx context.Context) ([]api.Policy, error) {
|
|||||||
// Get get policy info
|
// Get get policy info
|
||||||
// See more: https://docs.netbird.io/api/resources/policies#retrieve-a-policy
|
// See more: https://docs.netbird.io/api/resources/policies#retrieve-a-policy
|
||||||
func (a *PoliciesAPI) Get(ctx context.Context, policyID string) (*api.Policy, error) {
|
func (a *PoliciesAPI) Get(ctx context.Context, policyID string) (*api.Policy, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/policies/"+policyID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/policies/"+policyID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +50,7 @@ func (a *PoliciesAPI) Create(ctx context.Context, request api.PostApiPoliciesJSO
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/policies", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/policies", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -62,11 +64,13 @@ func (a *PoliciesAPI) Create(ctx context.Context, request api.PostApiPoliciesJSO
|
|||||||
// Update update policy info
|
// Update update policy info
|
||||||
// See more: https://docs.netbird.io/api/resources/policies#update-a-policy
|
// See more: https://docs.netbird.io/api/resources/policies#update-a-policy
|
||||||
func (a *PoliciesAPI) Update(ctx context.Context, policyID string, request api.PutApiPoliciesPolicyIdJSONRequestBody) (*api.Policy, error) {
|
func (a *PoliciesAPI) Update(ctx context.Context, policyID string, request api.PutApiPoliciesPolicyIdJSONRequestBody) (*api.Policy, error) {
|
||||||
|
path := "/api/policies/" + policyID
|
||||||
|
|
||||||
requestBytes, err := json.Marshal(request)
|
requestBytes, err := json.Marshal(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/policies/"+policyID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", path, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -80,7 +84,7 @@ func (a *PoliciesAPI) Update(ctx context.Context, policyID string, request api.P
|
|||||||
// Delete delete policy
|
// Delete delete policy
|
||||||
// See more: https://docs.netbird.io/api/resources/policies#delete-a-policy
|
// See more: https://docs.netbird.io/api/resources/policies#delete-a-policy
|
||||||
func (a *PoliciesAPI) Delete(ctx context.Context, policyID string) error {
|
func (a *PoliciesAPI) Delete(ctx context.Context, policyID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/policies/"+policyID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/policies/"+policyID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type PostureChecksAPI struct {
|
|||||||
// List list all posture checks
|
// List list all posture checks
|
||||||
// See more: https://docs.netbird.io/api/resources/posture-checks#list-all-posture-checks
|
// See more: https://docs.netbird.io/api/resources/posture-checks#list-all-posture-checks
|
||||||
func (a *PostureChecksAPI) List(ctx context.Context) ([]api.PostureCheck, error) {
|
func (a *PostureChecksAPI) List(ctx context.Context) ([]api.PostureCheck, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/posture-checks", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/posture-checks", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ func (a *PostureChecksAPI) List(ctx context.Context) ([]api.PostureCheck, error)
|
|||||||
// Get get posture check info
|
// Get get posture check info
|
||||||
// See more: https://docs.netbird.io/api/resources/posture-checks#retrieve-a-posture-check
|
// See more: https://docs.netbird.io/api/resources/posture-checks#retrieve-a-posture-check
|
||||||
func (a *PostureChecksAPI) Get(ctx context.Context, postureCheckID string) (*api.PostureCheck, error) {
|
func (a *PostureChecksAPI) Get(ctx context.Context, postureCheckID string) (*api.PostureCheck, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/posture-checks/"+postureCheckID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/posture-checks/"+postureCheckID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (a *PostureChecksAPI) Create(ctx context.Context, request api.PostApiPostur
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/posture-checks", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/posture-checks", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ func (a *PostureChecksAPI) Update(ctx context.Context, postureCheckID string, re
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/posture-checks/"+postureCheckID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/posture-checks/"+postureCheckID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ func (a *PostureChecksAPI) Update(ctx context.Context, postureCheckID string, re
|
|||||||
// Delete delete posture check
|
// Delete delete posture check
|
||||||
// See more: https://docs.netbird.io/api/resources/posture-checks#delete-a-posture-check
|
// See more: https://docs.netbird.io/api/resources/posture-checks#delete-a-posture-check
|
||||||
func (a *PostureChecksAPI) Delete(ctx context.Context, postureCheckID string) error {
|
func (a *PostureChecksAPI) Delete(ctx context.Context, postureCheckID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/posture-checks/"+postureCheckID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/posture-checks/"+postureCheckID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type RoutesAPI struct {
|
|||||||
// List list all routes
|
// List list all routes
|
||||||
// See more: https://docs.netbird.io/api/resources/routes#list-all-routes
|
// See more: https://docs.netbird.io/api/resources/routes#list-all-routes
|
||||||
func (a *RoutesAPI) List(ctx context.Context) ([]api.Route, error) {
|
func (a *RoutesAPI) List(ctx context.Context) ([]api.Route, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/routes", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/routes", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ func (a *RoutesAPI) List(ctx context.Context) ([]api.Route, error) {
|
|||||||
// Get get route info
|
// Get get route info
|
||||||
// See more: https://docs.netbird.io/api/resources/routes#retrieve-a-route
|
// See more: https://docs.netbird.io/api/resources/routes#retrieve-a-route
|
||||||
func (a *RoutesAPI) Get(ctx context.Context, routeID string) (*api.Route, error) {
|
func (a *RoutesAPI) Get(ctx context.Context, routeID string) (*api.Route, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/routes/"+routeID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/routes/"+routeID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (a *RoutesAPI) Create(ctx context.Context, request api.PostApiRoutesJSONReq
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/routes", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/routes", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ func (a *RoutesAPI) Update(ctx context.Context, routeID string, request api.PutA
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/routes/"+routeID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/routes/"+routeID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ func (a *RoutesAPI) Update(ctx context.Context, routeID string, request api.PutA
|
|||||||
// Delete delete route
|
// Delete delete route
|
||||||
// See more: https://docs.netbird.io/api/resources/routes#delete-a-route
|
// See more: https://docs.netbird.io/api/resources/routes#delete-a-route
|
||||||
func (a *RoutesAPI) Delete(ctx context.Context, routeID string) error {
|
func (a *RoutesAPI) Delete(ctx context.Context, routeID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/routes/"+routeID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/routes/"+routeID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type SetupKeysAPI struct {
|
|||||||
// List list all setup keys
|
// List list all setup keys
|
||||||
// See more: https://docs.netbird.io/api/resources/setup-keys#list-all-setup-keys
|
// See more: https://docs.netbird.io/api/resources/setup-keys#list-all-setup-keys
|
||||||
func (a *SetupKeysAPI) List(ctx context.Context) ([]api.SetupKey, error) {
|
func (a *SetupKeysAPI) List(ctx context.Context) ([]api.SetupKey, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/setup-keys", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/setup-keys", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ func (a *SetupKeysAPI) List(ctx context.Context) ([]api.SetupKey, error) {
|
|||||||
// Get get setup key info
|
// Get get setup key info
|
||||||
// See more: https://docs.netbird.io/api/resources/setup-keys#retrieve-a-setup-key
|
// See more: https://docs.netbird.io/api/resources/setup-keys#retrieve-a-setup-key
|
||||||
func (a *SetupKeysAPI) Get(ctx context.Context, setupKeyID string) (*api.SetupKey, error) {
|
func (a *SetupKeysAPI) Get(ctx context.Context, setupKeyID string) (*api.SetupKey, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/setup-keys/"+setupKeyID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/setup-keys/"+setupKeyID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -44,11 +44,13 @@ func (a *SetupKeysAPI) Get(ctx context.Context, setupKeyID string) (*api.SetupKe
|
|||||||
// Create generate new Setup Key
|
// Create generate new Setup Key
|
||||||
// See more: https://docs.netbird.io/api/resources/setup-keys#create-a-setup-key
|
// See more: https://docs.netbird.io/api/resources/setup-keys#create-a-setup-key
|
||||||
func (a *SetupKeysAPI) Create(ctx context.Context, request api.PostApiSetupKeysJSONRequestBody) (*api.SetupKeyClear, error) {
|
func (a *SetupKeysAPI) Create(ctx context.Context, request api.PostApiSetupKeysJSONRequestBody) (*api.SetupKeyClear, error) {
|
||||||
|
path := "/api/setup-keys"
|
||||||
|
|
||||||
requestBytes, err := json.Marshal(request)
|
requestBytes, err := json.Marshal(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/setup-keys", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", path, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -66,7 +68,7 @@ func (a *SetupKeysAPI) Update(ctx context.Context, setupKeyID string, request ap
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/setup-keys/"+setupKeyID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/setup-keys/"+setupKeyID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -80,7 +82,7 @@ func (a *SetupKeysAPI) Update(ctx context.Context, setupKeyID string, request ap
|
|||||||
// Delete delete setup key
|
// Delete delete setup key
|
||||||
// See more: https://docs.netbird.io/api/resources/setup-keys#delete-a-setup-key
|
// See more: https://docs.netbird.io/api/resources/setup-keys#delete-a-setup-key
|
||||||
func (a *SetupKeysAPI) Delete(ctx context.Context, setupKeyID string) error {
|
func (a *SetupKeysAPI) Delete(ctx context.Context, setupKeyID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/setup-keys/"+setupKeyID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/setup-keys/"+setupKeyID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type TokensAPI struct {
|
|||||||
// List list user tokens
|
// List list user tokens
|
||||||
// See more: https://docs.netbird.io/api/resources/tokens#list-all-tokens
|
// See more: https://docs.netbird.io/api/resources/tokens#list-all-tokens
|
||||||
func (a *TokensAPI) List(ctx context.Context, userID string) ([]api.PersonalAccessToken, error) {
|
func (a *TokensAPI) List(ctx context.Context, userID string) ([]api.PersonalAccessToken, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/users/"+userID+"/tokens", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/users/"+userID+"/tokens", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ func (a *TokensAPI) List(ctx context.Context, userID string) ([]api.PersonalAcce
|
|||||||
// Get get user token info
|
// Get get user token info
|
||||||
// See more: https://docs.netbird.io/api/resources/tokens#retrieve-a-token
|
// See more: https://docs.netbird.io/api/resources/tokens#retrieve-a-token
|
||||||
func (a *TokensAPI) Get(ctx context.Context, userID, tokenID string) (*api.PersonalAccessToken, error) {
|
func (a *TokensAPI) Get(ctx context.Context, userID, tokenID string) (*api.PersonalAccessToken, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/users/"+userID+"/tokens/"+tokenID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/users/"+userID+"/tokens/"+tokenID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (a *TokensAPI) Create(ctx context.Context, userID string, request api.PostA
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/users/"+userID+"/tokens", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/users/"+userID+"/tokens", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ func (a *TokensAPI) Create(ctx context.Context, userID string, request api.PostA
|
|||||||
// Delete delete user token
|
// Delete delete user token
|
||||||
// See more: https://docs.netbird.io/api/resources/tokens#delete-a-token
|
// See more: https://docs.netbird.io/api/resources/tokens#delete-a-token
|
||||||
func (a *TokensAPI) Delete(ctx context.Context, userID, tokenID string) error {
|
func (a *TokensAPI) Delete(ctx context.Context, userID, tokenID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/users/"+userID+"/tokens/"+tokenID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/users/"+userID+"/tokens/"+tokenID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type UsersAPI struct {
|
|||||||
// List list all users, only returns one user always
|
// List list all users, only returns one user always
|
||||||
// See more: https://docs.netbird.io/api/resources/users#list-all-users
|
// See more: https://docs.netbird.io/api/resources/users#list-all-users
|
||||||
func (a *UsersAPI) List(ctx context.Context) ([]api.User, error) {
|
func (a *UsersAPI) List(ctx context.Context) ([]api.User, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/users", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/users", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ func (a *UsersAPI) Create(ctx context.Context, request api.PostApiUsersJSONReque
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/users", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/users", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ func (a *UsersAPI) Update(ctx context.Context, userID string, request api.PutApi
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/users/"+userID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/users/"+userID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ func (a *UsersAPI) Update(ctx context.Context, userID string, request api.PutApi
|
|||||||
// Delete delete user
|
// Delete delete user
|
||||||
// See more: https://docs.netbird.io/api/resources/users#delete-a-user
|
// See more: https://docs.netbird.io/api/resources/users#delete-a-user
|
||||||
func (a *UsersAPI) Delete(ctx context.Context, userID string) error {
|
func (a *UsersAPI) Delete(ctx context.Context, userID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/users/"+userID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/users/"+userID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ func (a *UsersAPI) Delete(ctx context.Context, userID string) error {
|
|||||||
// ResendInvitation resend user invitation
|
// ResendInvitation resend user invitation
|
||||||
// See more: https://docs.netbird.io/api/resources/users#resend-user-invitation
|
// See more: https://docs.netbird.io/api/resources/users#resend-user-invitation
|
||||||
func (a *UsersAPI) ResendInvitation(ctx context.Context, userID string) error {
|
func (a *UsersAPI) ResendInvitation(ctx context.Context, userID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/users/"+userID+"/invite", nil)
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/users/"+userID+"/invite", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ func (a *UsersAPI) ResendInvitation(ctx context.Context, userID string) error {
|
|||||||
// Current gets the current user info
|
// Current gets the current user info
|
||||||
// See more: https://docs.netbird.io/api/resources/users#retrieve-current-user
|
// See more: https://docs.netbird.io/api/resources/users#retrieve-current-user
|
||||||
func (a *UsersAPI) Current(ctx context.Context) (*api.User, error) {
|
func (a *UsersAPI) Current(ctx context.Context) (*api.User, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/users/current", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/users/current", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -603,11 +603,15 @@ func (am *DefaultAccountManager) DeleteAccount(ctx context.Context, accountID, u
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, otherUser := range account.Users {
|
for _, otherUser := range account.Users {
|
||||||
if otherUser.IsServiceUser {
|
if otherUser.Id == userID {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if otherUser.Id == userID {
|
if otherUser.IsServiceUser {
|
||||||
|
err = am.deleteServiceUser(ctx, accountID, userID, otherUser)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -853,6 +853,42 @@ func TestAccountManager_DeleteAccount(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
account.Users["service-user-1"] = &types.User{
|
||||||
|
Id: "service-user-1",
|
||||||
|
Role: types.UserRoleAdmin,
|
||||||
|
IsServiceUser: true,
|
||||||
|
Issued: types.UserIssuedAPI,
|
||||||
|
PATs: map[string]*types.PersonalAccessToken{
|
||||||
|
"pat-1": {
|
||||||
|
ID: "pat-1",
|
||||||
|
UserID: "service-user-1",
|
||||||
|
Name: "service-user-1",
|
||||||
|
HashedToken: "hashedToken",
|
||||||
|
CreatedAt: time.Now(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
account.Users[userId] = &types.User{
|
||||||
|
Id: "service-user-2",
|
||||||
|
Role: types.UserRoleUser,
|
||||||
|
IsServiceUser: true,
|
||||||
|
Issued: types.UserIssuedAPI,
|
||||||
|
PATs: map[string]*types.PersonalAccessToken{
|
||||||
|
"pat-2": {
|
||||||
|
ID: "pat-2",
|
||||||
|
UserID: userId,
|
||||||
|
Name: userId,
|
||||||
|
HashedToken: "hashedToken",
|
||||||
|
CreatedAt: time.Now(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err = manager.Store.SaveAccount(context.Background(), account)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
err = manager.DeleteAccount(context.Background(), account.Id, userId)
|
err = manager.DeleteAccount(context.Background(), account.Id, userId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -862,6 +898,14 @@ func TestAccountManager_DeleteAccount(t *testing.T) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal(fmt.Errorf("expected to get an error when trying to get deleted account, got %v", getAccount))
|
t.Fatal(fmt.Errorf("expected to get an error when trying to get deleted account, got %v", getAccount))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pats, err := manager.Store.GetUserPATs(context.Background(), store.LockingStrengthShare, "service-user-1")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Len(t, pats, 0)
|
||||||
|
|
||||||
|
pats, err = manager.Store.GetUserPATs(context.Background(), store.LockingStrengthShare, userId)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Len(t, pats, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkTest_GetAccountWithclaims(b *testing.B) {
|
func BenchmarkTest_GetAccountWithclaims(b *testing.B) {
|
||||||
|
|||||||
@@ -1683,18 +1683,26 @@ func (s *SqlStore) SavePolicy(ctx context.Context, lockStrength LockingStrength,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *SqlStore) DeletePolicy(ctx context.Context, lockStrength LockingStrength, accountID, policyID string) error {
|
func (s *SqlStore) DeletePolicy(ctx context.Context, lockStrength LockingStrength, accountID, policyID string) error {
|
||||||
result := s.db.Clauses(clause.Locking{Strength: string(lockStrength)}).
|
return s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||||
Delete(&types.Policy{}, accountAndIDQueryCondition, accountID, policyID)
|
if err := tx.Where("policy_id = ?", policyID).Delete(&types.PolicyRule{}).Error; err != nil {
|
||||||
if err := result.Error; err != nil {
|
return fmt.Errorf("delete policy rules: %w", err)
|
||||||
log.WithContext(ctx).Errorf("failed to delete policy from store: %s", err)
|
}
|
||||||
return status.Errorf(status.Internal, "failed to delete policy from store")
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.RowsAffected == 0 {
|
result := tx.Clauses(clause.Locking{Strength: string(lockStrength)}).
|
||||||
return status.NewPolicyNotFoundError(policyID)
|
Where(accountAndIDQueryCondition, accountID, policyID).
|
||||||
}
|
Delete(&types.Policy{})
|
||||||
|
|
||||||
return nil
|
if err := result.Error; err != nil {
|
||||||
|
log.WithContext(ctx).Errorf("failed to delete policy from store: %s", err)
|
||||||
|
return status.Errorf(status.Internal, "failed to delete policy from store")
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.RowsAffected == 0 {
|
||||||
|
return status.NewPolicyNotFoundError(policyID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccountPostureChecks retrieves posture checks for an account.
|
// GetAccountPostureChecks retrieves posture checks for an account.
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ func (s *SharedSocket) read(receiver receiver) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReadFrom reads packets received in the packetDemux channel
|
// ReadFrom reads packets received in the packetDemux channel
|
||||||
func (s *SharedSocket) ReadFrom(b []byte) (n int, addr net.Addr, err error) {
|
func (s *SharedSocket) ReadFrom(b []byte) (int, net.Addr, error) {
|
||||||
var pkt rcvdPacket
|
var pkt rcvdPacket
|
||||||
select {
|
select {
|
||||||
case <-s.ctx.Done():
|
case <-s.ctx.Done():
|
||||||
@@ -263,8 +263,7 @@ func (s *SharedSocket) ReadFrom(b []byte) (n int, addr net.Addr, err error) {
|
|||||||
|
|
||||||
decodedLayers := make([]gopacket.LayerType, 0, 3)
|
decodedLayers := make([]gopacket.LayerType, 0, 3)
|
||||||
|
|
||||||
err = parser.DecodeLayers(pkt.buf, &decodedLayers)
|
if err := parser.DecodeLayers(pkt.buf, &decodedLayers); err != nil {
|
||||||
if err != nil {
|
|
||||||
return 0, nil, err
|
return 0, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,8 +272,8 @@ func (s *SharedSocket) ReadFrom(b []byte) (n int, addr net.Addr, err error) {
|
|||||||
Port: int(udp.SrcPort),
|
Port: int(udp.SrcPort),
|
||||||
}
|
}
|
||||||
|
|
||||||
copy(b, payload)
|
n := copy(b, payload)
|
||||||
return int(udp.Length), remoteAddr, nil
|
return n, remoteAddr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteTo builds a UDP packet and writes it using the specific IP version writer
|
// WriteTo builds a UDP packet and writes it using the specific IP version writer
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ func (registry *Registry) Register(peer *Peer) {
|
|||||||
p, loaded := registry.Peers.LoadOrStore(peer.Id, peer)
|
p, loaded := registry.Peers.LoadOrStore(peer.Id, peer)
|
||||||
if loaded {
|
if loaded {
|
||||||
pp := p.(*Peer)
|
pp := p.(*Peer)
|
||||||
log.Warnf("peer [%s] is already registered [new streamID %d, previous StreamID %d]. Will override stream.",
|
log.Tracef("peer [%s] is already registered [new streamID %d, previous StreamID %d]. Will override stream.",
|
||||||
peer.Id, peer.StreamID, pp.StreamID)
|
peer.Id, peer.StreamID, pp.StreamID)
|
||||||
registry.Peers.Store(peer.Id, peer)
|
registry.Peers.Store(peer.Id, peer)
|
||||||
return
|
return
|
||||||
@@ -104,7 +104,7 @@ func (registry *Registry) Deregister(peer *Peer) {
|
|||||||
pp := p.(*Peer)
|
pp := p.(*Peer)
|
||||||
if peer.StreamID < pp.StreamID {
|
if peer.StreamID < pp.StreamID {
|
||||||
registry.Peers.Store(peer.Id, p)
|
registry.Peers.Store(peer.Id, p)
|
||||||
log.Warnf("attempted to remove newer registered stream of a peer [%s] [newer streamID %d, previous StreamID %d]. Ignoring.",
|
log.Debugf("attempted to remove newer registered stream of a peer [%s] [newer streamID %d, previous StreamID %d]. Ignoring.",
|
||||||
peer.Id, pp.StreamID, peer.StreamID)
|
peer.Id, pp.StreamID, peer.StreamID)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/netbirdio/signal-dispatcher/dispatcher"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
"go.opentelemetry.io/otel/metric"
|
"go.opentelemetry.io/otel/metric"
|
||||||
@@ -15,6 +14,8 @@ import (
|
|||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
gproto "google.golang.org/protobuf/proto"
|
gproto "google.golang.org/protobuf/proto"
|
||||||
|
|
||||||
|
"github.com/netbirdio/signal-dispatcher/dispatcher"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/signal/metrics"
|
"github.com/netbirdio/netbird/signal/metrics"
|
||||||
"github.com/netbirdio/netbird/signal/peer"
|
"github.com/netbirdio/netbird/signal/peer"
|
||||||
"github.com/netbirdio/netbird/signal/proto"
|
"github.com/netbirdio/netbird/signal/proto"
|
||||||
@@ -28,10 +29,11 @@ const (
|
|||||||
labelTypeStream = "stream"
|
labelTypeStream = "stream"
|
||||||
labelTypeMessage = "message"
|
labelTypeMessage = "message"
|
||||||
|
|
||||||
labelError = "error"
|
labelError = "error"
|
||||||
labelErrorMissingId = "missing_id"
|
labelErrorMissingId = "missing_id"
|
||||||
labelErrorMissingMeta = "missing_meta"
|
labelErrorMissingMeta = "missing_meta"
|
||||||
labelErrorFailedHeader = "failed_header"
|
labelErrorFailedHeader = "failed_header"
|
||||||
|
labelErrorFailedRegistration = "failed_registration"
|
||||||
|
|
||||||
labelRegistrationStatus = "status"
|
labelRegistrationStatus = "status"
|
||||||
labelRegistrationFound = "found"
|
labelRegistrationFound = "found"
|
||||||
@@ -69,7 +71,7 @@ func NewServer(ctx context.Context, meter metric.Meter) (*Server, error) {
|
|||||||
|
|
||||||
// Send forwards a message to the signal peer
|
// Send forwards a message to the signal peer
|
||||||
func (s *Server) Send(ctx context.Context, msg *proto.EncryptedMessage) (*proto.EncryptedMessage, error) {
|
func (s *Server) Send(ctx context.Context, msg *proto.EncryptedMessage) (*proto.EncryptedMessage, error) {
|
||||||
log.Debugf("received a new message to send from peer [%s] to peer [%s]", msg.Key, msg.RemoteKey)
|
log.Tracef("received a new message to send from peer [%s] to peer [%s]", msg.Key, msg.RemoteKey)
|
||||||
|
|
||||||
if _, found := s.registry.Get(msg.RemoteKey); found {
|
if _, found := s.registry.Get(msg.RemoteKey); found {
|
||||||
s.forwardMessageToPeer(ctx, msg)
|
s.forwardMessageToPeer(ctx, msg)
|
||||||
@@ -112,7 +114,7 @@ func (s *Server) ConnectStream(stream proto.SignalExchange_ConnectStreamServer)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Received a response from peer [%s] to peer [%s]", msg.Key, msg.RemoteKey)
|
log.Tracef("Received a response from peer [%s] to peer [%s]", msg.Key, msg.RemoteKey)
|
||||||
|
|
||||||
_, err = s.dispatcher.SendMessage(stream.Context(), msg)
|
_, err = s.dispatcher.SendMessage(stream.Context(), msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -138,7 +140,12 @@ func (s *Server) RegisterPeer(stream proto.SignalExchange_ConnectStreamServer) (
|
|||||||
|
|
||||||
p := peer.NewPeer(id[0], stream)
|
p := peer.NewPeer(id[0], stream)
|
||||||
s.registry.Register(p)
|
s.registry.Register(p)
|
||||||
s.dispatcher.ListenForMessages(stream.Context(), p.Id, s.forwardMessageToPeer)
|
err := s.dispatcher.ListenForMessages(stream.Context(), p.Id, s.forwardMessageToPeer)
|
||||||
|
if err != nil {
|
||||||
|
s.metrics.RegistrationFailures.Add(stream.Context(), 1, metric.WithAttributes(attribute.String(labelError, labelErrorFailedRegistration)))
|
||||||
|
log.Errorf("error while registering message listener for peer [%s] %v", p.Id, err)
|
||||||
|
return nil, status.Errorf(codes.Internal, "error while registering message listener")
|
||||||
|
}
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +156,7 @@ func (s *Server) DeregisterPeer(p *peer.Peer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) forwardMessageToPeer(ctx context.Context, msg *proto.EncryptedMessage) {
|
func (s *Server) forwardMessageToPeer(ctx context.Context, msg *proto.EncryptedMessage) {
|
||||||
log.Debugf("forwarding a new message from peer [%s] to peer [%s]", msg.Key, msg.RemoteKey)
|
log.Tracef("forwarding a new message from peer [%s] to peer [%s]", msg.Key, msg.RemoteKey)
|
||||||
getRegistrationStart := time.Now()
|
getRegistrationStart := time.Now()
|
||||||
|
|
||||||
// lookup the target peer where the message is going to
|
// lookup the target peer where the message is going to
|
||||||
@@ -168,7 +175,7 @@ func (s *Server) forwardMessageToPeer(ctx context.Context, msg *proto.EncryptedM
|
|||||||
|
|
||||||
// forward the message to the target peer
|
// forward the message to the target peer
|
||||||
if err := dstPeer.Stream.Send(msg); err != nil {
|
if err := dstPeer.Stream.Send(msg); err != nil {
|
||||||
log.Warnf("error while forwarding message from peer [%s] to peer [%s] %v", msg.Key, msg.RemoteKey, err)
|
log.Tracef("error while forwarding message from peer [%s] to peer [%s] %v", msg.Key, msg.RemoteKey, err)
|
||||||
// todo respond to the sender?
|
// todo respond to the sender?
|
||||||
s.metrics.MessageForwardFailures.Add(ctx, 1, metric.WithAttributes(attribute.String(labelType, labelTypeError)))
|
s.metrics.MessageForwardFailures.Add(ctx, 1, metric.WithAttributes(attribute.String(labelType, labelTypeError)))
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user