mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-23 02:36:42 +00:00
Compare commits
11 Commits
poc/prepro
...
v0.50.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e6eede152 | ||
|
|
a76c8eafb4 | ||
|
|
2b9f331980 | ||
|
|
a7ea881900 | ||
|
|
8632dd15f1 | ||
|
|
e3b40ba694 | ||
|
|
e59d75d56a | ||
|
|
408f423adc | ||
|
|
f17dd3619c | ||
|
|
969f1ed59a | ||
|
|
768ba24fda |
@@ -43,7 +43,7 @@ jobs:
|
|||||||
- name: gomobile init
|
- name: gomobile init
|
||||||
run: gomobile init
|
run: gomobile init
|
||||||
- name: build android netbird lib
|
- name: build android netbird lib
|
||||||
run: PATH=$PATH:$(go env GOPATH) gomobile bind -o $GITHUB_WORKSPACE/netbird.aar -javapkg=io.netbird.gomobile -ldflags="-X golang.zx2c4.com/wireguard/ipc.socketDirectory=/data/data/io.netbird.client/cache/wireguard -X github.com/netbirdio/netbird/version.version=buildtest" $GITHUB_WORKSPACE/client/android
|
run: PATH=$PATH:$(go env GOPATH) gomobile bind -o $GITHUB_WORKSPACE/netbird.aar -javapkg=io.netbird.gomobile -ldflags="-checklinkname=0 -X golang.zx2c4.com/wireguard/ipc.socketDirectory=/data/data/io.netbird.client/cache/wireguard -X github.com/netbirdio/netbird/version.version=buildtest" $GITHUB_WORKSPACE/client/android
|
||||||
env:
|
env:
|
||||||
CGO_ENABLED: 0
|
CGO_ENABLED: 0
|
||||||
ANDROID_NDK_HOME: /usr/local/lib/android/sdk/ndk/23.1.7779620
|
ANDROID_NDK_HOME: /usr/local/lib/android/sdk/ndk/23.1.7779620
|
||||||
|
|||||||
@@ -50,10 +50,9 @@
|
|||||||
|
|
||||||
**Secure.** NetBird enables secure remote access by applying granular access policies while allowing you to manage them intuitively from a single place. Works universally on any infrastructure.
|
**Secure.** NetBird enables secure remote access by applying granular access policies while allowing you to manage them intuitively from a single place. Works universally on any infrastructure.
|
||||||
|
|
||||||
### Open-Source Network Security in a Single Platform
|
### Open Source Network Security in a Single Platform
|
||||||
|
|
||||||
|
<img width="1188" alt="centralized-network-management 1" src="https://github.com/user-attachments/assets/c28cc8e4-15d2-4d2f-bb97-a6433db39d56" />
|
||||||

|
|
||||||
|
|
||||||
### NetBird on Lawrence Systems (Video)
|
### NetBird on Lawrence Systems (Video)
|
||||||
[](https://www.youtube.com/watch?v=Kwrff6h0rEw)
|
[](https://www.youtube.com/watch?v=Kwrff6h0rEw)
|
||||||
|
|||||||
@@ -64,7 +64,9 @@ type Client struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewClient instantiate a new Client
|
// NewClient instantiate a new Client
|
||||||
func NewClient(cfgFile, deviceName string, uiVersion string, tunAdapter TunAdapter, iFaceDiscover IFaceDiscover, networkChangeListener NetworkChangeListener) *Client {
|
func NewClient(cfgFile string, androidSDKVersion int, deviceName string, uiVersion string, tunAdapter TunAdapter, iFaceDiscover IFaceDiscover, networkChangeListener NetworkChangeListener) *Client {
|
||||||
|
execWorkaround(androidSDKVersion)
|
||||||
|
|
||||||
net.SetAndroidProtectSocketFn(tunAdapter.ProtectSocket)
|
net.SetAndroidProtectSocketFn(tunAdapter.ProtectSocket)
|
||||||
return &Client{
|
return &Client{
|
||||||
cfgFile: cfgFile,
|
cfgFile: cfgFile,
|
||||||
|
|||||||
26
client/android/exec.go
Normal file
26
client/android/exec.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
//go:build android
|
||||||
|
|
||||||
|
package android
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
_ "unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://github.com/golang/go/pull/69543/commits/aad6b3b32c81795f86bc4a9e81aad94899daf520
|
||||||
|
// In Android version 11 and earlier, pidfd-related system calls
|
||||||
|
// are not allowed by the seccomp policy, which causes crashes due
|
||||||
|
// to SIGSYS signals.
|
||||||
|
|
||||||
|
//go:linkname checkPidfdOnce os.checkPidfdOnce
|
||||||
|
var checkPidfdOnce func() error
|
||||||
|
|
||||||
|
func execWorkaround(androidSDKVersion int) {
|
||||||
|
if androidSDKVersion > 30 { // above Android 11
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
checkPidfdOnce = func() error {
|
||||||
|
return fmt.Errorf("unsupported Android version")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,10 +17,18 @@ import (
|
|||||||
"github.com/netbirdio/netbird/client/server"
|
"github.com/netbirdio/netbird/client/server"
|
||||||
nbstatus "github.com/netbirdio/netbird/client/status"
|
nbstatus "github.com/netbirdio/netbird/client/status"
|
||||||
mgmProto "github.com/netbirdio/netbird/management/proto"
|
mgmProto "github.com/netbirdio/netbird/management/proto"
|
||||||
|
"github.com/netbirdio/netbird/upload-server/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
const errCloseConnection = "Failed to close connection: %v"
|
const errCloseConnection = "Failed to close connection: %v"
|
||||||
|
|
||||||
|
var (
|
||||||
|
logFileCount uint32
|
||||||
|
systemInfoFlag bool
|
||||||
|
uploadBundleFlag bool
|
||||||
|
uploadBundleURLFlag string
|
||||||
|
)
|
||||||
|
|
||||||
var debugCmd = &cobra.Command{
|
var debugCmd = &cobra.Command{
|
||||||
Use: "debug",
|
Use: "debug",
|
||||||
Short: "Debugging commands",
|
Short: "Debugging commands",
|
||||||
@@ -88,12 +96,13 @@ func debugBundle(cmd *cobra.Command, _ []string) error {
|
|||||||
|
|
||||||
client := proto.NewDaemonServiceClient(conn)
|
client := proto.NewDaemonServiceClient(conn)
|
||||||
request := &proto.DebugBundleRequest{
|
request := &proto.DebugBundleRequest{
|
||||||
Anonymize: anonymizeFlag,
|
Anonymize: anonymizeFlag,
|
||||||
Status: getStatusOutput(cmd, anonymizeFlag),
|
Status: getStatusOutput(cmd, anonymizeFlag),
|
||||||
SystemInfo: debugSystemInfoFlag,
|
SystemInfo: systemInfoFlag,
|
||||||
|
LogFileCount: logFileCount,
|
||||||
}
|
}
|
||||||
if debugUploadBundle {
|
if uploadBundleFlag {
|
||||||
request.UploadURL = debugUploadBundleURL
|
request.UploadURL = uploadBundleURLFlag
|
||||||
}
|
}
|
||||||
resp, err := client.DebugBundle(cmd.Context(), request)
|
resp, err := client.DebugBundle(cmd.Context(), request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -105,7 +114,7 @@ func debugBundle(cmd *cobra.Command, _ []string) error {
|
|||||||
return fmt.Errorf("upload failed: %s", resp.GetUploadFailureReason())
|
return fmt.Errorf("upload failed: %s", resp.GetUploadFailureReason())
|
||||||
}
|
}
|
||||||
|
|
||||||
if debugUploadBundle {
|
if uploadBundleFlag {
|
||||||
cmd.Printf("Upload file key:\n%s\n", resp.GetUploadedKey())
|
cmd.Printf("Upload file key:\n%s\n", resp.GetUploadedKey())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,12 +232,13 @@ func runForDuration(cmd *cobra.Command, args []string) error {
|
|||||||
headerPreDown := fmt.Sprintf("----- Netbird pre-down - Timestamp: %s - Duration: %s", time.Now().Format(time.RFC3339), duration)
|
headerPreDown := fmt.Sprintf("----- Netbird pre-down - Timestamp: %s - Duration: %s", time.Now().Format(time.RFC3339), duration)
|
||||||
statusOutput = fmt.Sprintf("%s\n%s\n%s", statusOutput, headerPreDown, getStatusOutput(cmd, anonymizeFlag))
|
statusOutput = fmt.Sprintf("%s\n%s\n%s", statusOutput, headerPreDown, getStatusOutput(cmd, anonymizeFlag))
|
||||||
request := &proto.DebugBundleRequest{
|
request := &proto.DebugBundleRequest{
|
||||||
Anonymize: anonymizeFlag,
|
Anonymize: anonymizeFlag,
|
||||||
Status: statusOutput,
|
Status: statusOutput,
|
||||||
SystemInfo: debugSystemInfoFlag,
|
SystemInfo: systemInfoFlag,
|
||||||
|
LogFileCount: logFileCount,
|
||||||
}
|
}
|
||||||
if debugUploadBundle {
|
if uploadBundleFlag {
|
||||||
request.UploadURL = debugUploadBundleURL
|
request.UploadURL = uploadBundleURLFlag
|
||||||
}
|
}
|
||||||
resp, err := client.DebugBundle(cmd.Context(), request)
|
resp, err := client.DebugBundle(cmd.Context(), request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -255,7 +265,7 @@ func runForDuration(cmd *cobra.Command, args []string) error {
|
|||||||
return fmt.Errorf("upload failed: %s", resp.GetUploadFailureReason())
|
return fmt.Errorf("upload failed: %s", resp.GetUploadFailureReason())
|
||||||
}
|
}
|
||||||
|
|
||||||
if debugUploadBundle {
|
if uploadBundleFlag {
|
||||||
cmd.Printf("Upload file key:\n%s\n", resp.GetUploadedKey())
|
cmd.Printf("Upload file key:\n%s\n", resp.GetUploadedKey())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,3 +385,15 @@ func generateDebugBundle(config *internal.Config, recorder *peer.Status, connect
|
|||||||
}
|
}
|
||||||
log.Infof("Generated debug bundle from SIGUSR1 at: %s", path)
|
log.Infof("Generated debug bundle from SIGUSR1 at: %s", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
debugBundleCmd.Flags().Uint32VarP(&logFileCount, "log-file-count", "C", 1, "Number of rotated log files to include in debug bundle")
|
||||||
|
debugBundleCmd.Flags().BoolVarP(&systemInfoFlag, "system-info", "S", true, "Adds system information to the debug bundle")
|
||||||
|
debugBundleCmd.Flags().BoolVarP(&uploadBundleFlag, "upload-bundle", "U", false, "Uploads the debug bundle to a server")
|
||||||
|
debugBundleCmd.Flags().StringVar(&uploadBundleURLFlag, "upload-bundle-url", types.DefaultBundleURL, "Service URL to get an URL to upload the debug bundle")
|
||||||
|
|
||||||
|
forCmd.Flags().Uint32VarP(&logFileCount, "log-file-count", "C", 1, "Number of rotated log files to include in debug bundle")
|
||||||
|
forCmd.Flags().BoolVarP(&systemInfoFlag, "system-info", "S", true, "Adds system information to the debug bundle")
|
||||||
|
forCmd.Flags().BoolVarP(&uploadBundleFlag, "upload-bundle", "U", false, "Uploads the debug bundle to a server")
|
||||||
|
forCmd.Flags().StringVar(&uploadBundleURLFlag, "upload-bundle-url", types.DefaultBundleURL, "Service URL to get an URL to upload the debug bundle")
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import (
|
|||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/client/internal"
|
"github.com/netbirdio/netbird/client/internal"
|
||||||
"github.com/netbirdio/netbird/upload-server/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -38,10 +37,7 @@ const (
|
|||||||
serverSSHAllowedFlag = "allow-server-ssh"
|
serverSSHAllowedFlag = "allow-server-ssh"
|
||||||
extraIFaceBlackListFlag = "extra-iface-blacklist"
|
extraIFaceBlackListFlag = "extra-iface-blacklist"
|
||||||
dnsRouteIntervalFlag = "dns-router-interval"
|
dnsRouteIntervalFlag = "dns-router-interval"
|
||||||
systemInfoFlag = "system-info"
|
|
||||||
enableLazyConnectionFlag = "enable-lazy-connection"
|
enableLazyConnectionFlag = "enable-lazy-connection"
|
||||||
uploadBundle = "upload-bundle"
|
|
||||||
uploadBundleURL = "upload-bundle-url"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -75,10 +71,7 @@ var (
|
|||||||
autoConnectDisabled bool
|
autoConnectDisabled bool
|
||||||
extraIFaceBlackList []string
|
extraIFaceBlackList []string
|
||||||
anonymizeFlag bool
|
anonymizeFlag bool
|
||||||
debugSystemInfoFlag bool
|
|
||||||
dnsRouteInterval time.Duration
|
dnsRouteInterval time.Duration
|
||||||
debugUploadBundle bool
|
|
||||||
debugUploadBundleURL string
|
|
||||||
lazyConnEnabled bool
|
lazyConnEnabled bool
|
||||||
|
|
||||||
rootCmd = &cobra.Command{
|
rootCmd = &cobra.Command{
|
||||||
@@ -184,11 +177,8 @@ func init() {
|
|||||||
upCmd.PersistentFlags().BoolVar(&rosenpassPermissive, rosenpassPermissiveFlag, false, "[Experimental] Enable Rosenpass in permissive mode to allow this peer to accept WireGuard connections without requiring Rosenpass functionality from peers that do not have Rosenpass enabled.")
|
upCmd.PersistentFlags().BoolVar(&rosenpassPermissive, rosenpassPermissiveFlag, false, "[Experimental] Enable Rosenpass in permissive mode to allow this peer to accept WireGuard connections without requiring Rosenpass functionality from peers that do not have Rosenpass enabled.")
|
||||||
upCmd.PersistentFlags().BoolVar(&serverSSHAllowed, serverSSHAllowedFlag, false, "Allow SSH server on peer. If enabled, the SSH server will be permitted")
|
upCmd.PersistentFlags().BoolVar(&serverSSHAllowed, serverSSHAllowedFlag, false, "Allow SSH server on peer. If enabled, the SSH server will be permitted")
|
||||||
upCmd.PersistentFlags().BoolVar(&autoConnectDisabled, disableAutoConnectFlag, false, "Disables auto-connect feature. If enabled, then the client won't connect automatically when the service starts.")
|
upCmd.PersistentFlags().BoolVar(&autoConnectDisabled, disableAutoConnectFlag, false, "Disables auto-connect feature. If enabled, then the client won't connect automatically when the service starts.")
|
||||||
upCmd.PersistentFlags().BoolVar(&lazyConnEnabled, enableLazyConnectionFlag, false, "[Experimental] Enable the lazy connection feature. If enabled, the client will establish connections on-demand.")
|
upCmd.PersistentFlags().BoolVar(&lazyConnEnabled, enableLazyConnectionFlag, false, "[Experimental] Enable the lazy connection feature. If enabled, the client will establish connections on-demand. Note: this setting may be overridden by management configuration.")
|
||||||
|
|
||||||
debugCmd.PersistentFlags().BoolVarP(&debugSystemInfoFlag, systemInfoFlag, "S", true, "Adds system information to the debug bundle")
|
|
||||||
debugCmd.PersistentFlags().BoolVarP(&debugUploadBundle, uploadBundle, "U", false, fmt.Sprintf("Uploads the debug bundle to a server from URL defined by %s", uploadBundleURL))
|
|
||||||
debugCmd.PersistentFlags().StringVar(&debugUploadBundleURL, uploadBundleURL, types.DefaultBundleURL, "Service URL to get an URL to upload the debug bundle")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetupCloseHandler handles SIGTERM signal and exits with success
|
// SetupCloseHandler handles SIGTERM signal and exits with success
|
||||||
|
|||||||
@@ -34,14 +34,14 @@ func NewActivityRecorder() *ActivityRecorder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetLastActivities returns a snapshot of peer last activity
|
// GetLastActivities returns a snapshot of peer last activity
|
||||||
func (r *ActivityRecorder) GetLastActivities() map[string]time.Time {
|
func (r *ActivityRecorder) GetLastActivities() map[string]monotime.Time {
|
||||||
r.mu.RLock()
|
r.mu.RLock()
|
||||||
defer r.mu.RUnlock()
|
defer r.mu.RUnlock()
|
||||||
|
|
||||||
activities := make(map[string]time.Time, len(r.peers))
|
activities := make(map[string]monotime.Time, len(r.peers))
|
||||||
for key, record := range r.peers {
|
for key, record := range r.peers {
|
||||||
unixNano := record.LastActivity.Load()
|
monoTime := record.LastActivity.Load()
|
||||||
activities[key] = time.Unix(0, unixNano)
|
activities[key] = monotime.Time(monoTime)
|
||||||
}
|
}
|
||||||
return activities
|
return activities
|
||||||
}
|
}
|
||||||
@@ -51,18 +51,20 @@ func (r *ActivityRecorder) UpsertAddress(publicKey string, address netip.AddrPor
|
|||||||
r.mu.Lock()
|
r.mu.Lock()
|
||||||
defer r.mu.Unlock()
|
defer r.mu.Unlock()
|
||||||
|
|
||||||
if pr, exists := r.peers[publicKey]; exists {
|
var record *PeerRecord
|
||||||
delete(r.addrToPeer, pr.Address)
|
record, exists := r.peers[publicKey]
|
||||||
pr.Address = address
|
if exists {
|
||||||
|
delete(r.addrToPeer, record.Address)
|
||||||
|
record.Address = address
|
||||||
} else {
|
} else {
|
||||||
record := &PeerRecord{
|
record = &PeerRecord{
|
||||||
Address: address,
|
Address: address,
|
||||||
}
|
}
|
||||||
record.LastActivity.Store(monotime.Now())
|
record.LastActivity.Store(int64(monotime.Now()))
|
||||||
r.peers[publicKey] = record
|
r.peers[publicKey] = record
|
||||||
}
|
}
|
||||||
|
|
||||||
r.addrToPeer[address] = r.peers[publicKey]
|
r.addrToPeer[address] = record
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ActivityRecorder) Remove(publicKey string) {
|
func (r *ActivityRecorder) Remove(publicKey string) {
|
||||||
@@ -84,7 +86,7 @@ func (r *ActivityRecorder) record(address netip.AddrPort) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
now := monotime.Now()
|
now := int64(monotime.Now())
|
||||||
last := record.LastActivity.Load()
|
last := record.LastActivity.Load()
|
||||||
if now-last < saveFrequency {
|
if now-last < saveFrequency {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import (
|
|||||||
"net/netip"
|
"net/netip"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/netbirdio/netbird/monotime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestActivityRecorder_GetLastActivities(t *testing.T) {
|
func TestActivityRecorder_GetLastActivities(t *testing.T) {
|
||||||
@@ -17,11 +19,7 @@ func TestActivityRecorder_GetLastActivities(t *testing.T) {
|
|||||||
t.Fatalf("Expected activity for peer %s, but got none", peer)
|
t.Fatalf("Expected activity for peer %s, but got none", peer)
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.IsZero() {
|
if monotime.Since(p) > 5*time.Second {
|
||||||
t.Fatalf("Expected activity for peer %s, but got zero", peer)
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Before(time.Now().Add(-2 * time.Minute)) {
|
|
||||||
t.Fatalf("Expected activity for peer %s to be recent, but got %v", peer, p)
|
t.Fatalf("Expected activity for peer %s to be recent, but got %v", peer, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import (
|
|||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"golang.zx2c4.com/wireguard/wgctrl"
|
"golang.zx2c4.com/wireguard/wgctrl"
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
|
|
||||||
|
"github.com/netbirdio/netbird/monotime"
|
||||||
)
|
)
|
||||||
|
|
||||||
var zeroKey wgtypes.Key
|
var zeroKey wgtypes.Key
|
||||||
@@ -277,6 +279,6 @@ func (c *KernelConfigurer) GetStats() (map[string]WGStats, error) {
|
|||||||
return stats, nil
|
return stats, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *KernelConfigurer) LastActivities() map[string]time.Time {
|
func (c *KernelConfigurer) LastActivities() map[string]monotime.Time {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/client/iface/bind"
|
"github.com/netbirdio/netbird/client/iface/bind"
|
||||||
|
"github.com/netbirdio/netbird/monotime"
|
||||||
nbnet "github.com/netbirdio/netbird/util/net"
|
nbnet "github.com/netbirdio/netbird/util/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -223,7 +224,7 @@ func (c *WGUSPConfigurer) FullStats() (*Stats, error) {
|
|||||||
return parseStatus(c.deviceName, ipcStr)
|
return parseStatus(c.deviceName, ipcStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *WGUSPConfigurer) LastActivities() map[string]time.Time {
|
func (c *WGUSPConfigurer) LastActivities() map[string]monotime.Time {
|
||||||
return c.activityRecorder.GetLastActivities()
|
return c.activityRecorder.GetLastActivities()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/client/iface/configurer"
|
"github.com/netbirdio/netbird/client/iface/configurer"
|
||||||
|
"github.com/netbirdio/netbird/monotime"
|
||||||
)
|
)
|
||||||
|
|
||||||
type WGConfigurer interface {
|
type WGConfigurer interface {
|
||||||
@@ -19,5 +20,5 @@ type WGConfigurer interface {
|
|||||||
Close()
|
Close()
|
||||||
GetStats() (map[string]configurer.WGStats, error)
|
GetStats() (map[string]configurer.WGStats, error)
|
||||||
FullStats() (*configurer.Stats, error)
|
FullStats() (*configurer.Stats, error)
|
||||||
LastActivities() map[string]time.Time
|
LastActivities() map[string]monotime.Time
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import (
|
|||||||
"github.com/netbirdio/netbird/client/iface/device"
|
"github.com/netbirdio/netbird/client/iface/device"
|
||||||
"github.com/netbirdio/netbird/client/iface/wgaddr"
|
"github.com/netbirdio/netbird/client/iface/wgaddr"
|
||||||
"github.com/netbirdio/netbird/client/iface/wgproxy"
|
"github.com/netbirdio/netbird/client/iface/wgproxy"
|
||||||
|
"github.com/netbirdio/netbird/monotime"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -29,6 +30,11 @@ const (
|
|||||||
WgInterfaceDefault = configurer.WgInterfaceDefault
|
WgInterfaceDefault = configurer.WgInterfaceDefault
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrIfaceNotFound is returned when the WireGuard interface is not found
|
||||||
|
ErrIfaceNotFound = fmt.Errorf("wireguard interface not found")
|
||||||
|
)
|
||||||
|
|
||||||
type wgProxyFactory interface {
|
type wgProxyFactory interface {
|
||||||
GetProxy() wgproxy.Proxy
|
GetProxy() wgproxy.Proxy
|
||||||
Free() error
|
Free() error
|
||||||
@@ -117,6 +123,9 @@ func (w *WGIface) UpdateAddr(newAddr string) error {
|
|||||||
func (w *WGIface) UpdatePeer(peerKey string, allowedIps []netip.Prefix, keepAlive time.Duration, endpoint *net.UDPAddr, preSharedKey *wgtypes.Key) error {
|
func (w *WGIface) UpdatePeer(peerKey string, allowedIps []netip.Prefix, keepAlive time.Duration, endpoint *net.UDPAddr, preSharedKey *wgtypes.Key) error {
|
||||||
w.mu.Lock()
|
w.mu.Lock()
|
||||||
defer w.mu.Unlock()
|
defer w.mu.Unlock()
|
||||||
|
if w.configurer == nil {
|
||||||
|
return ErrIfaceNotFound
|
||||||
|
}
|
||||||
|
|
||||||
log.Debugf("updating interface %s peer %s, endpoint %s, allowedIPs %v", w.tun.DeviceName(), peerKey, endpoint, allowedIps)
|
log.Debugf("updating interface %s peer %s, endpoint %s, allowedIPs %v", w.tun.DeviceName(), peerKey, endpoint, allowedIps)
|
||||||
return w.configurer.UpdatePeer(peerKey, allowedIps, keepAlive, endpoint, preSharedKey)
|
return w.configurer.UpdatePeer(peerKey, allowedIps, keepAlive, endpoint, preSharedKey)
|
||||||
@@ -126,6 +135,9 @@ func (w *WGIface) UpdatePeer(peerKey string, allowedIps []netip.Prefix, keepAliv
|
|||||||
func (w *WGIface) RemovePeer(peerKey string) error {
|
func (w *WGIface) RemovePeer(peerKey string) error {
|
||||||
w.mu.Lock()
|
w.mu.Lock()
|
||||||
defer w.mu.Unlock()
|
defer w.mu.Unlock()
|
||||||
|
if w.configurer == nil {
|
||||||
|
return ErrIfaceNotFound
|
||||||
|
}
|
||||||
|
|
||||||
log.Debugf("Removing peer %s from interface %s ", peerKey, w.tun.DeviceName())
|
log.Debugf("Removing peer %s from interface %s ", peerKey, w.tun.DeviceName())
|
||||||
return w.configurer.RemovePeer(peerKey)
|
return w.configurer.RemovePeer(peerKey)
|
||||||
@@ -135,6 +147,9 @@ func (w *WGIface) RemovePeer(peerKey string) error {
|
|||||||
func (w *WGIface) AddAllowedIP(peerKey string, allowedIP netip.Prefix) error {
|
func (w *WGIface) AddAllowedIP(peerKey string, allowedIP netip.Prefix) error {
|
||||||
w.mu.Lock()
|
w.mu.Lock()
|
||||||
defer w.mu.Unlock()
|
defer w.mu.Unlock()
|
||||||
|
if w.configurer == nil {
|
||||||
|
return ErrIfaceNotFound
|
||||||
|
}
|
||||||
|
|
||||||
log.Debugf("Adding allowed IP to interface %s and peer %s: allowed IP %s ", w.tun.DeviceName(), peerKey, allowedIP)
|
log.Debugf("Adding allowed IP to interface %s and peer %s: allowed IP %s ", w.tun.DeviceName(), peerKey, allowedIP)
|
||||||
return w.configurer.AddAllowedIP(peerKey, allowedIP)
|
return w.configurer.AddAllowedIP(peerKey, allowedIP)
|
||||||
@@ -144,6 +159,9 @@ func (w *WGIface) AddAllowedIP(peerKey string, allowedIP netip.Prefix) error {
|
|||||||
func (w *WGIface) RemoveAllowedIP(peerKey string, allowedIP netip.Prefix) error {
|
func (w *WGIface) RemoveAllowedIP(peerKey string, allowedIP netip.Prefix) error {
|
||||||
w.mu.Lock()
|
w.mu.Lock()
|
||||||
defer w.mu.Unlock()
|
defer w.mu.Unlock()
|
||||||
|
if w.configurer == nil {
|
||||||
|
return ErrIfaceNotFound
|
||||||
|
}
|
||||||
|
|
||||||
log.Debugf("Removing allowed IP from interface %s and peer %s: allowed IP %s ", w.tun.DeviceName(), peerKey, allowedIP)
|
log.Debugf("Removing allowed IP from interface %s and peer %s: allowed IP %s ", w.tun.DeviceName(), peerKey, allowedIP)
|
||||||
return w.configurer.RemoveAllowedIP(peerKey, allowedIP)
|
return w.configurer.RemoveAllowedIP(peerKey, allowedIP)
|
||||||
@@ -214,18 +232,29 @@ func (w *WGIface) GetWGDevice() *wgdevice.Device {
|
|||||||
|
|
||||||
// GetStats returns the last handshake time, rx and tx bytes
|
// GetStats returns the last handshake time, rx and tx bytes
|
||||||
func (w *WGIface) GetStats() (map[string]configurer.WGStats, error) {
|
func (w *WGIface) GetStats() (map[string]configurer.WGStats, error) {
|
||||||
|
if w.configurer == nil {
|
||||||
|
return nil, ErrIfaceNotFound
|
||||||
|
}
|
||||||
return w.configurer.GetStats()
|
return w.configurer.GetStats()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WGIface) LastActivities() map[string]time.Time {
|
func (w *WGIface) LastActivities() map[string]monotime.Time {
|
||||||
w.mu.Lock()
|
w.mu.Lock()
|
||||||
defer w.mu.Unlock()
|
defer w.mu.Unlock()
|
||||||
|
|
||||||
|
if w.configurer == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return w.configurer.LastActivities()
|
return w.configurer.LastActivities()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *WGIface) FullStats() (*configurer.Stats, error) {
|
func (w *WGIface) FullStats() (*configurer.Stats, error) {
|
||||||
|
if w.configurer == nil {
|
||||||
|
return nil, ErrIfaceNotFound
|
||||||
|
}
|
||||||
|
|
||||||
return w.configurer.FullStats()
|
return w.configurer.FullStats()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -226,7 +226,6 @@ func (e *ConnMgr) ActivatePeer(ctx context.Context, conn *peer.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if found := e.lazyConnMgr.ActivatePeer(conn.GetKey()); found {
|
if found := e.lazyConnMgr.ActivatePeer(conn.GetKey()); found {
|
||||||
conn.Log.Infof("activated peer from inactive state")
|
|
||||||
if err := conn.Open(ctx); err != nil {
|
if err := conn.Open(ctx); err != nil {
|
||||||
conn.Log.Errorf("failed to open connection: %v", err)
|
conn.Log.Errorf("failed to open connection: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ type BundleGenerator struct {
|
|||||||
anonymize bool
|
anonymize bool
|
||||||
clientStatus string
|
clientStatus string
|
||||||
includeSystemInfo bool
|
includeSystemInfo bool
|
||||||
|
logFileCount uint32
|
||||||
|
|
||||||
archive *zip.Writer
|
archive *zip.Writer
|
||||||
}
|
}
|
||||||
@@ -175,6 +176,7 @@ type BundleConfig struct {
|
|||||||
Anonymize bool
|
Anonymize bool
|
||||||
ClientStatus string
|
ClientStatus string
|
||||||
IncludeSystemInfo bool
|
IncludeSystemInfo bool
|
||||||
|
LogFileCount uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type GeneratorDependencies struct {
|
type GeneratorDependencies struct {
|
||||||
@@ -185,6 +187,12 @@ type GeneratorDependencies struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewBundleGenerator(deps GeneratorDependencies, cfg BundleConfig) *BundleGenerator {
|
func NewBundleGenerator(deps GeneratorDependencies, cfg BundleConfig) *BundleGenerator {
|
||||||
|
// Default to 1 log file for backward compatibility when 0 is provided
|
||||||
|
logFileCount := cfg.LogFileCount
|
||||||
|
if logFileCount == 0 {
|
||||||
|
logFileCount = 1
|
||||||
|
}
|
||||||
|
|
||||||
return &BundleGenerator{
|
return &BundleGenerator{
|
||||||
anonymizer: anonymize.NewAnonymizer(anonymize.DefaultAddresses()),
|
anonymizer: anonymize.NewAnonymizer(anonymize.DefaultAddresses()),
|
||||||
|
|
||||||
@@ -196,6 +204,7 @@ func NewBundleGenerator(deps GeneratorDependencies, cfg BundleConfig) *BundleGen
|
|||||||
anonymize: cfg.Anonymize,
|
anonymize: cfg.Anonymize,
|
||||||
clientStatus: cfg.ClientStatus,
|
clientStatus: cfg.ClientStatus,
|
||||||
includeSystemInfo: cfg.IncludeSystemInfo,
|
includeSystemInfo: cfg.IncludeSystemInfo,
|
||||||
|
logFileCount: logFileCount,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -561,32 +570,8 @@ func (g *BundleGenerator) addLogfile() error {
|
|||||||
return fmt.Errorf("add client log file to zip: %w", err)
|
return fmt.Errorf("add client log file to zip: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// add latest rotated log file
|
// add rotated log files based on logFileCount
|
||||||
pattern := filepath.Join(logDir, "client-*.log.gz")
|
g.addRotatedLogFiles(logDir)
|
||||||
files, err := filepath.Glob(pattern)
|
|
||||||
if err != nil {
|
|
||||||
log.Warnf("failed to glob rotated logs: %v", err)
|
|
||||||
} else if len(files) > 0 {
|
|
||||||
// pick the file with the latest ModTime
|
|
||||||
sort.Slice(files, func(i, j int) bool {
|
|
||||||
fi, err := os.Stat(files[i])
|
|
||||||
if err != nil {
|
|
||||||
log.Warnf("failed to stat rotated log %s: %v", files[i], err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
fj, err := os.Stat(files[j])
|
|
||||||
if err != nil {
|
|
||||||
log.Warnf("failed to stat rotated log %s: %v", files[j], err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return fi.ModTime().Before(fj.ModTime())
|
|
||||||
})
|
|
||||||
latest := files[len(files)-1]
|
|
||||||
name := filepath.Base(latest)
|
|
||||||
if err := g.addSingleLogFileGz(latest, name); err != nil {
|
|
||||||
log.Warnf("failed to add rotated log %s: %v", name, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stdErrLogPath := filepath.Join(logDir, errorLogFile)
|
stdErrLogPath := filepath.Join(logDir, errorLogFile)
|
||||||
stdoutLogPath := filepath.Join(logDir, stdoutLogFile)
|
stdoutLogPath := filepath.Join(logDir, stdoutLogFile)
|
||||||
@@ -670,6 +655,52 @@ func (g *BundleGenerator) addSingleLogFileGz(logPath, targetName string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addRotatedLogFiles adds rotated log files to the bundle based on logFileCount
|
||||||
|
func (g *BundleGenerator) addRotatedLogFiles(logDir string) {
|
||||||
|
if g.logFileCount == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pattern := filepath.Join(logDir, "client-*.log.gz")
|
||||||
|
files, err := filepath.Glob(pattern)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("failed to glob rotated logs: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(files) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort files by modification time (newest first)
|
||||||
|
sort.Slice(files, func(i, j int) bool {
|
||||||
|
fi, err := os.Stat(files[i])
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("failed to stat rotated log %s: %v", files[i], err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
fj, err := os.Stat(files[j])
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("failed to stat rotated log %s: %v", files[j], err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return fi.ModTime().After(fj.ModTime())
|
||||||
|
})
|
||||||
|
|
||||||
|
// include up to logFileCount rotated files
|
||||||
|
maxFiles := int(g.logFileCount)
|
||||||
|
if maxFiles > len(files) {
|
||||||
|
maxFiles = len(files)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < maxFiles; i++ {
|
||||||
|
name := filepath.Base(files[i])
|
||||||
|
if err := g.addSingleLogFileGz(files[i], name); err != nil {
|
||||||
|
log.Warnf("failed to add rotated log %s: %v", name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (g *BundleGenerator) addFileToZip(reader io.Reader, filename string) error {
|
func (g *BundleGenerator) addFileToZip(reader io.Reader, filename string) error {
|
||||||
header := &zip.FileHeader{
|
header := &zip.FileHeader{
|
||||||
Name: filename,
|
Name: filename,
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ import (
|
|||||||
"github.com/netbirdio/netbird/management/server/store"
|
"github.com/netbirdio/netbird/management/server/store"
|
||||||
"github.com/netbirdio/netbird/management/server/telemetry"
|
"github.com/netbirdio/netbird/management/server/telemetry"
|
||||||
"github.com/netbirdio/netbird/management/server/types"
|
"github.com/netbirdio/netbird/management/server/types"
|
||||||
|
"github.com/netbirdio/netbird/monotime"
|
||||||
relayClient "github.com/netbirdio/netbird/relay/client"
|
relayClient "github.com/netbirdio/netbird/relay/client"
|
||||||
"github.com/netbirdio/netbird/route"
|
"github.com/netbirdio/netbird/route"
|
||||||
signal "github.com/netbirdio/netbird/signal/client"
|
signal "github.com/netbirdio/netbird/signal/client"
|
||||||
@@ -96,7 +97,7 @@ type MockWGIface struct {
|
|||||||
GetInterfaceGUIDStringFunc func() (string, error)
|
GetInterfaceGUIDStringFunc func() (string, error)
|
||||||
GetProxyFunc func() wgproxy.Proxy
|
GetProxyFunc func() wgproxy.Proxy
|
||||||
GetNetFunc func() *netstack.Net
|
GetNetFunc func() *netstack.Net
|
||||||
LastActivitiesFunc func() map[string]time.Time
|
LastActivitiesFunc func() map[string]monotime.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MockWGIface) FullStats() (*configurer.Stats, error) {
|
func (m *MockWGIface) FullStats() (*configurer.Stats, error) {
|
||||||
@@ -187,7 +188,7 @@ func (m *MockWGIface) GetNet() *netstack.Net {
|
|||||||
return m.GetNetFunc()
|
return m.GetNetFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MockWGIface) LastActivities() map[string]time.Time {
|
func (m *MockWGIface) LastActivities() map[string]monotime.Time {
|
||||||
if m.LastActivitiesFunc != nil {
|
if m.LastActivitiesFunc != nil {
|
||||||
return m.LastActivitiesFunc()
|
return m.LastActivitiesFunc()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/netbirdio/netbird/client/iface/device"
|
"github.com/netbirdio/netbird/client/iface/device"
|
||||||
"github.com/netbirdio/netbird/client/iface/wgaddr"
|
"github.com/netbirdio/netbird/client/iface/wgaddr"
|
||||||
"github.com/netbirdio/netbird/client/iface/wgproxy"
|
"github.com/netbirdio/netbird/client/iface/wgproxy"
|
||||||
|
"github.com/netbirdio/netbird/monotime"
|
||||||
)
|
)
|
||||||
|
|
||||||
type wgIfaceBase interface {
|
type wgIfaceBase interface {
|
||||||
@@ -38,5 +39,5 @@ type wgIfaceBase interface {
|
|||||||
GetStats() (map[string]configurer.WGStats, error)
|
GetStats() (map[string]configurer.WGStats, error)
|
||||||
GetNet() *netstack.Net
|
GetNet() *netstack.Net
|
||||||
FullStats() (*configurer.Stats, error)
|
FullStats() (*configurer.Stats, error)
|
||||||
LastActivities() map[string]time.Time
|
LastActivities() map[string]monotime.Time
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ func (d *Listener) ReadPackets() {
|
|||||||
n, remoteAddr, err := d.conn.ReadFromUDP(make([]byte, 1))
|
n, remoteAddr, err := d.conn.ReadFromUDP(make([]byte, 1))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if d.isClosed.Load() {
|
if d.isClosed.Load() {
|
||||||
d.peerCfg.Log.Debugf("exit from activity listener")
|
d.peerCfg.Log.Infof("exit from activity listener")
|
||||||
} else {
|
} else {
|
||||||
d.peerCfg.Log.Errorf("failed to read from activity listener: %s", err)
|
d.peerCfg.Log.Errorf("failed to read from activity listener: %s", err)
|
||||||
}
|
}
|
||||||
@@ -59,9 +59,11 @@ func (d *Listener) ReadPackets() {
|
|||||||
d.peerCfg.Log.Warnf("received %d bytes from %s, too short", n, remoteAddr)
|
d.peerCfg.Log.Warnf("received %d bytes from %s, too short", n, remoteAddr)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
d.peerCfg.Log.Infof("activity detected")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d.peerCfg.Log.Debugf("removing lazy endpoint: %s", d.endpoint.String())
|
||||||
if err := d.removeEndpoint(); err != nil {
|
if err := d.removeEndpoint(); err != nil {
|
||||||
d.peerCfg.Log.Errorf("failed to remove endpoint: %s", err)
|
d.peerCfg.Log.Errorf("failed to remove endpoint: %s", err)
|
||||||
}
|
}
|
||||||
@@ -71,7 +73,7 @@ func (d *Listener) ReadPackets() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Listener) Close() {
|
func (d *Listener) Close() {
|
||||||
d.peerCfg.Log.Infof("closing listener: %s", d.conn.LocalAddr().String())
|
d.peerCfg.Log.Infof("closing activity listener: %s", d.conn.LocalAddr().String())
|
||||||
d.isClosed.Store(true)
|
d.isClosed.Store(true)
|
||||||
|
|
||||||
if err := d.conn.Close(); err != nil {
|
if err := d.conn.Close(); err != nil {
|
||||||
@@ -81,7 +83,6 @@ func (d *Listener) Close() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Listener) removeEndpoint() error {
|
func (d *Listener) removeEndpoint() error {
|
||||||
d.peerCfg.Log.Debugf("removing lazy endpoint: %s", d.endpoint.String())
|
|
||||||
return d.wgIface.RemovePeer(d.peerCfg.PublicKey)
|
return d.wgIface.RemovePeer(d.peerCfg.PublicKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/client/internal/lazyconn"
|
"github.com/netbirdio/netbird/client/internal/lazyconn"
|
||||||
|
"github.com/netbirdio/netbird/monotime"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -18,7 +19,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type WgInterface interface {
|
type WgInterface interface {
|
||||||
LastActivities() map[string]time.Time
|
LastActivities() map[string]monotime.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type Manager struct {
|
type Manager struct {
|
||||||
@@ -124,6 +125,7 @@ func (m *Manager) checkStats() (map[string]struct{}, error) {
|
|||||||
|
|
||||||
idlePeers := make(map[string]struct{})
|
idlePeers := make(map[string]struct{})
|
||||||
|
|
||||||
|
checkTime := time.Now()
|
||||||
for peerID, peerCfg := range m.interestedPeers {
|
for peerID, peerCfg := range m.interestedPeers {
|
||||||
lastActive, ok := lastActivities[peerID]
|
lastActive, ok := lastActivities[peerID]
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -132,8 +134,9 @@ func (m *Manager) checkStats() (map[string]struct{}, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if time.Since(lastActive) > m.inactivityThreshold {
|
since := monotime.Since(lastActive)
|
||||||
peerCfg.Log.Infof("peer is inactive since: %v", lastActive)
|
if since > m.inactivityThreshold {
|
||||||
|
peerCfg.Log.Infof("peer is inactive since time: %s", checkTime.Add(-since).String())
|
||||||
idlePeers[peerID] = struct{}{}
|
idlePeers[peerID] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,13 +9,14 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/client/internal/lazyconn"
|
"github.com/netbirdio/netbird/client/internal/lazyconn"
|
||||||
|
"github.com/netbirdio/netbird/monotime"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mockWgInterface struct {
|
type mockWgInterface struct {
|
||||||
lastActivities map[string]time.Time
|
lastActivities map[string]monotime.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockWgInterface) LastActivities() map[string]time.Time {
|
func (m *mockWgInterface) LastActivities() map[string]monotime.Time {
|
||||||
return m.lastActivities
|
return m.lastActivities
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,8 +24,8 @@ func TestPeerTriggersInactivity(t *testing.T) {
|
|||||||
peerID := "peer1"
|
peerID := "peer1"
|
||||||
|
|
||||||
wgMock := &mockWgInterface{
|
wgMock := &mockWgInterface{
|
||||||
lastActivities: map[string]time.Time{
|
lastActivities: map[string]monotime.Time{
|
||||||
peerID: time.Now().Add(-20 * time.Minute),
|
peerID: monotime.Time(int64(monotime.Now()) - int64(20*time.Minute)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,8 +65,8 @@ func TestPeerTriggersActivity(t *testing.T) {
|
|||||||
peerID := "peer1"
|
peerID := "peer1"
|
||||||
|
|
||||||
wgMock := &mockWgInterface{
|
wgMock := &mockWgInterface{
|
||||||
lastActivities: map[string]time.Time{
|
lastActivities: map[string]monotime.Time{
|
||||||
peerID: time.Now().Add(-5 * time.Minute),
|
peerID: monotime.Time(int64(monotime.Now()) - int64(5*time.Minute)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -258,12 +258,13 @@ func (m *Manager) ActivatePeer(peerID string) (found bool) {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfg.Log.Infof("activate peer from inactive state by remote signal message")
|
||||||
|
|
||||||
if !m.activateSinglePeer(cfg, mp) {
|
if !m.activateSinglePeer(cfg, mp) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
m.activateHAGroupPeers(cfg)
|
m.activateHAGroupPeers(cfg)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -571,12 +572,12 @@ func (m *Manager) onPeerInactivityTimedOut(peerIDs map[string]struct{}) {
|
|||||||
// this is blocking operation, potentially can be optimized
|
// this is blocking operation, potentially can be optimized
|
||||||
m.peerStore.PeerConnIdle(mp.peerCfg.PublicKey)
|
m.peerStore.PeerConnIdle(mp.peerCfg.PublicKey)
|
||||||
|
|
||||||
mp.peerCfg.Log.Infof("start activity monitor")
|
|
||||||
|
|
||||||
mp.expectedWatcher = watcherActivity
|
mp.expectedWatcher = watcherActivity
|
||||||
|
|
||||||
m.inactivityManager.RemovePeer(mp.peerCfg.PublicKey)
|
m.inactivityManager.RemovePeer(mp.peerCfg.PublicKey)
|
||||||
|
|
||||||
|
mp.peerCfg.Log.Infof("start activity monitor")
|
||||||
|
|
||||||
if err := m.activityManager.MonitorPeerActivity(*mp.peerCfg); err != nil {
|
if err := m.activityManager.MonitorPeerActivity(*mp.peerCfg); err != nil {
|
||||||
mp.peerCfg.Log.Errorf("failed to create activity monitor: %v", err)
|
mp.peerCfg.Log.Errorf("failed to create activity monitor: %v", err)
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -6,11 +6,13 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
|
|
||||||
|
"github.com/netbirdio/netbird/monotime"
|
||||||
)
|
)
|
||||||
|
|
||||||
type WGIface interface {
|
type WGIface interface {
|
||||||
RemovePeer(peerKey string) error
|
RemovePeer(peerKey string) error
|
||||||
UpdatePeer(peerKey string, allowedIps []netip.Prefix, keepAlive time.Duration, endpoint *net.UDPAddr, preSharedKey *wgtypes.Key) error
|
UpdatePeer(peerKey string, allowedIps []netip.Prefix, keepAlive time.Duration, endpoint *net.UDPAddr, preSharedKey *wgtypes.Key) error
|
||||||
IsUserspaceBind() bool
|
IsUserspaceBind() bool
|
||||||
LastActivities() map[string]time.Time
|
LastActivities() map[string]monotime.Time
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2290,6 +2290,7 @@ type DebugBundleRequest struct {
|
|||||||
Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"`
|
Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"`
|
||||||
SystemInfo bool `protobuf:"varint,3,opt,name=systemInfo,proto3" json:"systemInfo,omitempty"`
|
SystemInfo bool `protobuf:"varint,3,opt,name=systemInfo,proto3" json:"systemInfo,omitempty"`
|
||||||
UploadURL string `protobuf:"bytes,4,opt,name=uploadURL,proto3" json:"uploadURL,omitempty"`
|
UploadURL string `protobuf:"bytes,4,opt,name=uploadURL,proto3" json:"uploadURL,omitempty"`
|
||||||
|
LogFileCount uint32 `protobuf:"varint,5,opt,name=logFileCount,proto3" json:"logFileCount,omitempty"`
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
@@ -2352,6 +2353,13 @@ func (x *DebugBundleRequest) GetUploadURL() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *DebugBundleRequest) GetLogFileCount() uint32 {
|
||||||
|
if x != nil {
|
||||||
|
return x.LogFileCount
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
type DebugBundleResponse struct {
|
type DebugBundleResponse struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
|
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
|
||||||
@@ -3746,14 +3754,15 @@ const file_daemon_proto_rawDesc = "" +
|
|||||||
"\x12translatedHostname\x18\x04 \x01(\tR\x12translatedHostname\x128\n" +
|
"\x12translatedHostname\x18\x04 \x01(\tR\x12translatedHostname\x128\n" +
|
||||||
"\x0etranslatedPort\x18\x05 \x01(\v2\x10.daemon.PortInfoR\x0etranslatedPort\"G\n" +
|
"\x0etranslatedPort\x18\x05 \x01(\v2\x10.daemon.PortInfoR\x0etranslatedPort\"G\n" +
|
||||||
"\x17ForwardingRulesResponse\x12,\n" +
|
"\x17ForwardingRulesResponse\x12,\n" +
|
||||||
"\x05rules\x18\x01 \x03(\v2\x16.daemon.ForwardingRuleR\x05rules\"\x88\x01\n" +
|
"\x05rules\x18\x01 \x03(\v2\x16.daemon.ForwardingRuleR\x05rules\"\xac\x01\n" +
|
||||||
"\x12DebugBundleRequest\x12\x1c\n" +
|
"\x12DebugBundleRequest\x12\x1c\n" +
|
||||||
"\tanonymize\x18\x01 \x01(\bR\tanonymize\x12\x16\n" +
|
"\tanonymize\x18\x01 \x01(\bR\tanonymize\x12\x16\n" +
|
||||||
"\x06status\x18\x02 \x01(\tR\x06status\x12\x1e\n" +
|
"\x06status\x18\x02 \x01(\tR\x06status\x12\x1e\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"systemInfo\x18\x03 \x01(\bR\n" +
|
"systemInfo\x18\x03 \x01(\bR\n" +
|
||||||
"systemInfo\x12\x1c\n" +
|
"systemInfo\x12\x1c\n" +
|
||||||
"\tuploadURL\x18\x04 \x01(\tR\tuploadURL\"}\n" +
|
"\tuploadURL\x18\x04 \x01(\tR\tuploadURL\x12\"\n" +
|
||||||
|
"\flogFileCount\x18\x05 \x01(\rR\flogFileCount\"}\n" +
|
||||||
"\x13DebugBundleResponse\x12\x12\n" +
|
"\x13DebugBundleResponse\x12\x12\n" +
|
||||||
"\x04path\x18\x01 \x01(\tR\x04path\x12 \n" +
|
"\x04path\x18\x01 \x01(\tR\x04path\x12 \n" +
|
||||||
"\vuploadedKey\x18\x02 \x01(\tR\vuploadedKey\x120\n" +
|
"\vuploadedKey\x18\x02 \x01(\tR\vuploadedKey\x120\n" +
|
||||||
|
|||||||
@@ -356,6 +356,7 @@ message DebugBundleRequest {
|
|||||||
string status = 2;
|
string status = 2;
|
||||||
bool systemInfo = 3;
|
bool systemInfo = 3;
|
||||||
string uploadURL = 4;
|
string uploadURL = 4;
|
||||||
|
uint32 logFileCount = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message DebugBundleResponse {
|
message DebugBundleResponse {
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
// versions:
|
|
||||||
// - protoc-gen-go-grpc v1.5.1
|
|
||||||
// - protoc v5.29.3
|
|
||||||
// source: daemon.proto
|
|
||||||
|
|
||||||
package proto
|
package proto
|
||||||
|
|
||||||
@@ -15,31 +11,8 @@ import (
|
|||||||
|
|
||||||
// This is a compile-time assertion to ensure that this generated file
|
// This is a compile-time assertion to ensure that this generated file
|
||||||
// is compatible with the grpc package it is being compiled against.
|
// is compatible with the grpc package it is being compiled against.
|
||||||
// Requires gRPC-Go v1.64.0 or later.
|
// Requires gRPC-Go v1.32.0 or later.
|
||||||
const _ = grpc.SupportPackageIsVersion9
|
const _ = grpc.SupportPackageIsVersion7
|
||||||
|
|
||||||
const (
|
|
||||||
DaemonService_Login_FullMethodName = "/daemon.DaemonService/Login"
|
|
||||||
DaemonService_WaitSSOLogin_FullMethodName = "/daemon.DaemonService/WaitSSOLogin"
|
|
||||||
DaemonService_Up_FullMethodName = "/daemon.DaemonService/Up"
|
|
||||||
DaemonService_Status_FullMethodName = "/daemon.DaemonService/Status"
|
|
||||||
DaemonService_Down_FullMethodName = "/daemon.DaemonService/Down"
|
|
||||||
DaemonService_GetConfig_FullMethodName = "/daemon.DaemonService/GetConfig"
|
|
||||||
DaemonService_ListNetworks_FullMethodName = "/daemon.DaemonService/ListNetworks"
|
|
||||||
DaemonService_SelectNetworks_FullMethodName = "/daemon.DaemonService/SelectNetworks"
|
|
||||||
DaemonService_DeselectNetworks_FullMethodName = "/daemon.DaemonService/DeselectNetworks"
|
|
||||||
DaemonService_ForwardingRules_FullMethodName = "/daemon.DaemonService/ForwardingRules"
|
|
||||||
DaemonService_DebugBundle_FullMethodName = "/daemon.DaemonService/DebugBundle"
|
|
||||||
DaemonService_GetLogLevel_FullMethodName = "/daemon.DaemonService/GetLogLevel"
|
|
||||||
DaemonService_SetLogLevel_FullMethodName = "/daemon.DaemonService/SetLogLevel"
|
|
||||||
DaemonService_ListStates_FullMethodName = "/daemon.DaemonService/ListStates"
|
|
||||||
DaemonService_CleanState_FullMethodName = "/daemon.DaemonService/CleanState"
|
|
||||||
DaemonService_DeleteState_FullMethodName = "/daemon.DaemonService/DeleteState"
|
|
||||||
DaemonService_SetNetworkMapPersistence_FullMethodName = "/daemon.DaemonService/SetNetworkMapPersistence"
|
|
||||||
DaemonService_TracePacket_FullMethodName = "/daemon.DaemonService/TracePacket"
|
|
||||||
DaemonService_SubscribeEvents_FullMethodName = "/daemon.DaemonService/SubscribeEvents"
|
|
||||||
DaemonService_GetEvents_FullMethodName = "/daemon.DaemonService/GetEvents"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DaemonServiceClient is the client API for DaemonService service.
|
// DaemonServiceClient is the client API for DaemonService service.
|
||||||
//
|
//
|
||||||
@@ -80,7 +53,7 @@ type DaemonServiceClient interface {
|
|||||||
// SetNetworkMapPersistence enables or disables network map persistence
|
// SetNetworkMapPersistence enables or disables network map persistence
|
||||||
SetNetworkMapPersistence(ctx context.Context, in *SetNetworkMapPersistenceRequest, opts ...grpc.CallOption) (*SetNetworkMapPersistenceResponse, error)
|
SetNetworkMapPersistence(ctx context.Context, in *SetNetworkMapPersistenceRequest, opts ...grpc.CallOption) (*SetNetworkMapPersistenceResponse, error)
|
||||||
TracePacket(ctx context.Context, in *TracePacketRequest, opts ...grpc.CallOption) (*TracePacketResponse, error)
|
TracePacket(ctx context.Context, in *TracePacketRequest, opts ...grpc.CallOption) (*TracePacketResponse, error)
|
||||||
SubscribeEvents(ctx context.Context, in *SubscribeRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[SystemEvent], error)
|
SubscribeEvents(ctx context.Context, in *SubscribeRequest, opts ...grpc.CallOption) (DaemonService_SubscribeEventsClient, error)
|
||||||
GetEvents(ctx context.Context, in *GetEventsRequest, opts ...grpc.CallOption) (*GetEventsResponse, error)
|
GetEvents(ctx context.Context, in *GetEventsRequest, opts ...grpc.CallOption) (*GetEventsResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,9 +66,8 @@ func NewDaemonServiceClient(cc grpc.ClientConnInterface) DaemonServiceClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error) {
|
func (c *daemonServiceClient) Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(LoginResponse)
|
out := new(LoginResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_Login_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/Login", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -103,9 +75,8 @@ func (c *daemonServiceClient) Login(ctx context.Context, in *LoginRequest, opts
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) WaitSSOLogin(ctx context.Context, in *WaitSSOLoginRequest, opts ...grpc.CallOption) (*WaitSSOLoginResponse, error) {
|
func (c *daemonServiceClient) WaitSSOLogin(ctx context.Context, in *WaitSSOLoginRequest, opts ...grpc.CallOption) (*WaitSSOLoginResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(WaitSSOLoginResponse)
|
out := new(WaitSSOLoginResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_WaitSSOLogin_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/WaitSSOLogin", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -113,9 +84,8 @@ func (c *daemonServiceClient) WaitSSOLogin(ctx context.Context, in *WaitSSOLogin
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) Up(ctx context.Context, in *UpRequest, opts ...grpc.CallOption) (*UpResponse, error) {
|
func (c *daemonServiceClient) Up(ctx context.Context, in *UpRequest, opts ...grpc.CallOption) (*UpResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(UpResponse)
|
out := new(UpResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_Up_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/Up", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -123,9 +93,8 @@ func (c *daemonServiceClient) Up(ctx context.Context, in *UpRequest, opts ...grp
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) {
|
func (c *daemonServiceClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(StatusResponse)
|
out := new(StatusResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_Status_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/Status", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -133,9 +102,8 @@ func (c *daemonServiceClient) Status(ctx context.Context, in *StatusRequest, opt
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) Down(ctx context.Context, in *DownRequest, opts ...grpc.CallOption) (*DownResponse, error) {
|
func (c *daemonServiceClient) Down(ctx context.Context, in *DownRequest, opts ...grpc.CallOption) (*DownResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(DownResponse)
|
out := new(DownResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_Down_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/Down", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -143,9 +111,8 @@ func (c *daemonServiceClient) Down(ctx context.Context, in *DownRequest, opts ..
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) GetConfig(ctx context.Context, in *GetConfigRequest, opts ...grpc.CallOption) (*GetConfigResponse, error) {
|
func (c *daemonServiceClient) GetConfig(ctx context.Context, in *GetConfigRequest, opts ...grpc.CallOption) (*GetConfigResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(GetConfigResponse)
|
out := new(GetConfigResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_GetConfig_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/GetConfig", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -153,9 +120,8 @@ func (c *daemonServiceClient) GetConfig(ctx context.Context, in *GetConfigReques
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) ListNetworks(ctx context.Context, in *ListNetworksRequest, opts ...grpc.CallOption) (*ListNetworksResponse, error) {
|
func (c *daemonServiceClient) ListNetworks(ctx context.Context, in *ListNetworksRequest, opts ...grpc.CallOption) (*ListNetworksResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(ListNetworksResponse)
|
out := new(ListNetworksResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_ListNetworks_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/ListNetworks", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -163,9 +129,8 @@ func (c *daemonServiceClient) ListNetworks(ctx context.Context, in *ListNetworks
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) SelectNetworks(ctx context.Context, in *SelectNetworksRequest, opts ...grpc.CallOption) (*SelectNetworksResponse, error) {
|
func (c *daemonServiceClient) SelectNetworks(ctx context.Context, in *SelectNetworksRequest, opts ...grpc.CallOption) (*SelectNetworksResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(SelectNetworksResponse)
|
out := new(SelectNetworksResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_SelectNetworks_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/SelectNetworks", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -173,9 +138,8 @@ func (c *daemonServiceClient) SelectNetworks(ctx context.Context, in *SelectNetw
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) DeselectNetworks(ctx context.Context, in *SelectNetworksRequest, opts ...grpc.CallOption) (*SelectNetworksResponse, error) {
|
func (c *daemonServiceClient) DeselectNetworks(ctx context.Context, in *SelectNetworksRequest, opts ...grpc.CallOption) (*SelectNetworksResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(SelectNetworksResponse)
|
out := new(SelectNetworksResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_DeselectNetworks_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/DeselectNetworks", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -183,9 +147,8 @@ func (c *daemonServiceClient) DeselectNetworks(ctx context.Context, in *SelectNe
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) ForwardingRules(ctx context.Context, in *EmptyRequest, opts ...grpc.CallOption) (*ForwardingRulesResponse, error) {
|
func (c *daemonServiceClient) ForwardingRules(ctx context.Context, in *EmptyRequest, opts ...grpc.CallOption) (*ForwardingRulesResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(ForwardingRulesResponse)
|
out := new(ForwardingRulesResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_ForwardingRules_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/ForwardingRules", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -193,9 +156,8 @@ func (c *daemonServiceClient) ForwardingRules(ctx context.Context, in *EmptyRequ
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) DebugBundle(ctx context.Context, in *DebugBundleRequest, opts ...grpc.CallOption) (*DebugBundleResponse, error) {
|
func (c *daemonServiceClient) DebugBundle(ctx context.Context, in *DebugBundleRequest, opts ...grpc.CallOption) (*DebugBundleResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(DebugBundleResponse)
|
out := new(DebugBundleResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_DebugBundle_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/DebugBundle", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -203,9 +165,8 @@ func (c *daemonServiceClient) DebugBundle(ctx context.Context, in *DebugBundleRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) GetLogLevel(ctx context.Context, in *GetLogLevelRequest, opts ...grpc.CallOption) (*GetLogLevelResponse, error) {
|
func (c *daemonServiceClient) GetLogLevel(ctx context.Context, in *GetLogLevelRequest, opts ...grpc.CallOption) (*GetLogLevelResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(GetLogLevelResponse)
|
out := new(GetLogLevelResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_GetLogLevel_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/GetLogLevel", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -213,9 +174,8 @@ func (c *daemonServiceClient) GetLogLevel(ctx context.Context, in *GetLogLevelRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) SetLogLevel(ctx context.Context, in *SetLogLevelRequest, opts ...grpc.CallOption) (*SetLogLevelResponse, error) {
|
func (c *daemonServiceClient) SetLogLevel(ctx context.Context, in *SetLogLevelRequest, opts ...grpc.CallOption) (*SetLogLevelResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(SetLogLevelResponse)
|
out := new(SetLogLevelResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_SetLogLevel_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/SetLogLevel", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -223,9 +183,8 @@ func (c *daemonServiceClient) SetLogLevel(ctx context.Context, in *SetLogLevelRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) ListStates(ctx context.Context, in *ListStatesRequest, opts ...grpc.CallOption) (*ListStatesResponse, error) {
|
func (c *daemonServiceClient) ListStates(ctx context.Context, in *ListStatesRequest, opts ...grpc.CallOption) (*ListStatesResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(ListStatesResponse)
|
out := new(ListStatesResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_ListStates_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/ListStates", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -233,9 +192,8 @@ func (c *daemonServiceClient) ListStates(ctx context.Context, in *ListStatesRequ
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) CleanState(ctx context.Context, in *CleanStateRequest, opts ...grpc.CallOption) (*CleanStateResponse, error) {
|
func (c *daemonServiceClient) CleanState(ctx context.Context, in *CleanStateRequest, opts ...grpc.CallOption) (*CleanStateResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(CleanStateResponse)
|
out := new(CleanStateResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_CleanState_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/CleanState", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -243,9 +201,8 @@ func (c *daemonServiceClient) CleanState(ctx context.Context, in *CleanStateRequ
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) DeleteState(ctx context.Context, in *DeleteStateRequest, opts ...grpc.CallOption) (*DeleteStateResponse, error) {
|
func (c *daemonServiceClient) DeleteState(ctx context.Context, in *DeleteStateRequest, opts ...grpc.CallOption) (*DeleteStateResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(DeleteStateResponse)
|
out := new(DeleteStateResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_DeleteState_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/DeleteState", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -253,9 +210,8 @@ func (c *daemonServiceClient) DeleteState(ctx context.Context, in *DeleteStateRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) SetNetworkMapPersistence(ctx context.Context, in *SetNetworkMapPersistenceRequest, opts ...grpc.CallOption) (*SetNetworkMapPersistenceResponse, error) {
|
func (c *daemonServiceClient) SetNetworkMapPersistence(ctx context.Context, in *SetNetworkMapPersistenceRequest, opts ...grpc.CallOption) (*SetNetworkMapPersistenceResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(SetNetworkMapPersistenceResponse)
|
out := new(SetNetworkMapPersistenceResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_SetNetworkMapPersistence_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/SetNetworkMapPersistence", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -263,22 +219,20 @@ func (c *daemonServiceClient) SetNetworkMapPersistence(ctx context.Context, in *
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) TracePacket(ctx context.Context, in *TracePacketRequest, opts ...grpc.CallOption) (*TracePacketResponse, error) {
|
func (c *daemonServiceClient) TracePacket(ctx context.Context, in *TracePacketRequest, opts ...grpc.CallOption) (*TracePacketResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(TracePacketResponse)
|
out := new(TracePacketResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_TracePacket_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/TracePacket", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) SubscribeEvents(ctx context.Context, in *SubscribeRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[SystemEvent], error) {
|
func (c *daemonServiceClient) SubscribeEvents(ctx context.Context, in *SubscribeRequest, opts ...grpc.CallOption) (DaemonService_SubscribeEventsClient, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
stream, err := c.cc.NewStream(ctx, &DaemonService_ServiceDesc.Streams[0], "/daemon.DaemonService/SubscribeEvents", opts...)
|
||||||
stream, err := c.cc.NewStream(ctx, &DaemonService_ServiceDesc.Streams[0], DaemonService_SubscribeEvents_FullMethodName, cOpts...)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
x := &grpc.GenericClientStream[SubscribeRequest, SystemEvent]{ClientStream: stream}
|
x := &daemonServiceSubscribeEventsClient{stream}
|
||||||
if err := x.ClientStream.SendMsg(in); err != nil {
|
if err := x.ClientStream.SendMsg(in); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -288,13 +242,26 @@ func (c *daemonServiceClient) SubscribeEvents(ctx context.Context, in *Subscribe
|
|||||||
return x, nil
|
return x, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
|
type DaemonService_SubscribeEventsClient interface {
|
||||||
type DaemonService_SubscribeEventsClient = grpc.ServerStreamingClient[SystemEvent]
|
Recv() (*SystemEvent, error)
|
||||||
|
grpc.ClientStream
|
||||||
|
}
|
||||||
|
|
||||||
|
type daemonServiceSubscribeEventsClient struct {
|
||||||
|
grpc.ClientStream
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *daemonServiceSubscribeEventsClient) Recv() (*SystemEvent, error) {
|
||||||
|
m := new(SystemEvent)
|
||||||
|
if err := x.ClientStream.RecvMsg(m); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *daemonServiceClient) GetEvents(ctx context.Context, in *GetEventsRequest, opts ...grpc.CallOption) (*GetEventsResponse, error) {
|
func (c *daemonServiceClient) GetEvents(ctx context.Context, in *GetEventsRequest, opts ...grpc.CallOption) (*GetEventsResponse, error) {
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(GetEventsResponse)
|
out := new(GetEventsResponse)
|
||||||
err := c.cc.Invoke(ctx, DaemonService_GetEvents_FullMethodName, in, out, cOpts...)
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/GetEvents", in, out, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -303,7 +270,7 @@ func (c *daemonServiceClient) GetEvents(ctx context.Context, in *GetEventsReques
|
|||||||
|
|
||||||
// DaemonServiceServer is the server API for DaemonService service.
|
// DaemonServiceServer is the server API for DaemonService service.
|
||||||
// All implementations must embed UnimplementedDaemonServiceServer
|
// All implementations must embed UnimplementedDaemonServiceServer
|
||||||
// for forward compatibility.
|
// for forward compatibility
|
||||||
type DaemonServiceServer interface {
|
type DaemonServiceServer interface {
|
||||||
// Login uses setup key to prepare configuration for the daemon.
|
// Login uses setup key to prepare configuration for the daemon.
|
||||||
Login(context.Context, *LoginRequest) (*LoginResponse, error)
|
Login(context.Context, *LoginRequest) (*LoginResponse, error)
|
||||||
@@ -340,17 +307,14 @@ type DaemonServiceServer interface {
|
|||||||
// SetNetworkMapPersistence enables or disables network map persistence
|
// SetNetworkMapPersistence enables or disables network map persistence
|
||||||
SetNetworkMapPersistence(context.Context, *SetNetworkMapPersistenceRequest) (*SetNetworkMapPersistenceResponse, error)
|
SetNetworkMapPersistence(context.Context, *SetNetworkMapPersistenceRequest) (*SetNetworkMapPersistenceResponse, error)
|
||||||
TracePacket(context.Context, *TracePacketRequest) (*TracePacketResponse, error)
|
TracePacket(context.Context, *TracePacketRequest) (*TracePacketResponse, error)
|
||||||
SubscribeEvents(*SubscribeRequest, grpc.ServerStreamingServer[SystemEvent]) error
|
SubscribeEvents(*SubscribeRequest, DaemonService_SubscribeEventsServer) error
|
||||||
GetEvents(context.Context, *GetEventsRequest) (*GetEventsResponse, error)
|
GetEvents(context.Context, *GetEventsRequest) (*GetEventsResponse, error)
|
||||||
mustEmbedUnimplementedDaemonServiceServer()
|
mustEmbedUnimplementedDaemonServiceServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnimplementedDaemonServiceServer must be embedded to have
|
// UnimplementedDaemonServiceServer must be embedded to have forward compatible implementations.
|
||||||
// forward compatible implementations.
|
type UnimplementedDaemonServiceServer struct {
|
||||||
//
|
}
|
||||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
|
||||||
// pointer dereference when methods are called.
|
|
||||||
type UnimplementedDaemonServiceServer struct{}
|
|
||||||
|
|
||||||
func (UnimplementedDaemonServiceServer) Login(context.Context, *LoginRequest) (*LoginResponse, error) {
|
func (UnimplementedDaemonServiceServer) Login(context.Context, *LoginRequest) (*LoginResponse, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method Login not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method Login not implemented")
|
||||||
@@ -406,14 +370,13 @@ func (UnimplementedDaemonServiceServer) SetNetworkMapPersistence(context.Context
|
|||||||
func (UnimplementedDaemonServiceServer) TracePacket(context.Context, *TracePacketRequest) (*TracePacketResponse, error) {
|
func (UnimplementedDaemonServiceServer) TracePacket(context.Context, *TracePacketRequest) (*TracePacketResponse, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method TracePacket not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method TracePacket not implemented")
|
||||||
}
|
}
|
||||||
func (UnimplementedDaemonServiceServer) SubscribeEvents(*SubscribeRequest, grpc.ServerStreamingServer[SystemEvent]) error {
|
func (UnimplementedDaemonServiceServer) SubscribeEvents(*SubscribeRequest, DaemonService_SubscribeEventsServer) error {
|
||||||
return status.Errorf(codes.Unimplemented, "method SubscribeEvents not implemented")
|
return status.Errorf(codes.Unimplemented, "method SubscribeEvents not implemented")
|
||||||
}
|
}
|
||||||
func (UnimplementedDaemonServiceServer) GetEvents(context.Context, *GetEventsRequest) (*GetEventsResponse, error) {
|
func (UnimplementedDaemonServiceServer) GetEvents(context.Context, *GetEventsRequest) (*GetEventsResponse, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method GetEvents not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method GetEvents not implemented")
|
||||||
}
|
}
|
||||||
func (UnimplementedDaemonServiceServer) mustEmbedUnimplementedDaemonServiceServer() {}
|
func (UnimplementedDaemonServiceServer) mustEmbedUnimplementedDaemonServiceServer() {}
|
||||||
func (UnimplementedDaemonServiceServer) testEmbeddedByValue() {}
|
|
||||||
|
|
||||||
// UnsafeDaemonServiceServer may be embedded to opt out of forward compatibility for this service.
|
// UnsafeDaemonServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||||
// Use of this interface is not recommended, as added methods to DaemonServiceServer will
|
// Use of this interface is not recommended, as added methods to DaemonServiceServer will
|
||||||
@@ -423,13 +386,6 @@ type UnsafeDaemonServiceServer interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func RegisterDaemonServiceServer(s grpc.ServiceRegistrar, srv DaemonServiceServer) {
|
func RegisterDaemonServiceServer(s grpc.ServiceRegistrar, srv DaemonServiceServer) {
|
||||||
// If the following call pancis, it indicates UnimplementedDaemonServiceServer was
|
|
||||||
// embedded by pointer and is nil. This will cause panics if an
|
|
||||||
// unimplemented method is ever invoked, so we test this at initialization
|
|
||||||
// time to prevent it from happening at runtime later due to I/O.
|
|
||||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
|
||||||
t.testEmbeddedByValue()
|
|
||||||
}
|
|
||||||
s.RegisterService(&DaemonService_ServiceDesc, srv)
|
s.RegisterService(&DaemonService_ServiceDesc, srv)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,7 +399,7 @@ func _DaemonService_Login_Handler(srv interface{}, ctx context.Context, dec func
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_Login_FullMethodName,
|
FullMethod: "/daemon.DaemonService/Login",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).Login(ctx, req.(*LoginRequest))
|
return srv.(DaemonServiceServer).Login(ctx, req.(*LoginRequest))
|
||||||
@@ -461,7 +417,7 @@ func _DaemonService_WaitSSOLogin_Handler(srv interface{}, ctx context.Context, d
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_WaitSSOLogin_FullMethodName,
|
FullMethod: "/daemon.DaemonService/WaitSSOLogin",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).WaitSSOLogin(ctx, req.(*WaitSSOLoginRequest))
|
return srv.(DaemonServiceServer).WaitSSOLogin(ctx, req.(*WaitSSOLoginRequest))
|
||||||
@@ -479,7 +435,7 @@ func _DaemonService_Up_Handler(srv interface{}, ctx context.Context, dec func(in
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_Up_FullMethodName,
|
FullMethod: "/daemon.DaemonService/Up",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).Up(ctx, req.(*UpRequest))
|
return srv.(DaemonServiceServer).Up(ctx, req.(*UpRequest))
|
||||||
@@ -497,7 +453,7 @@ func _DaemonService_Status_Handler(srv interface{}, ctx context.Context, dec fun
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_Status_FullMethodName,
|
FullMethod: "/daemon.DaemonService/Status",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).Status(ctx, req.(*StatusRequest))
|
return srv.(DaemonServiceServer).Status(ctx, req.(*StatusRequest))
|
||||||
@@ -515,7 +471,7 @@ func _DaemonService_Down_Handler(srv interface{}, ctx context.Context, dec func(
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_Down_FullMethodName,
|
FullMethod: "/daemon.DaemonService/Down",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).Down(ctx, req.(*DownRequest))
|
return srv.(DaemonServiceServer).Down(ctx, req.(*DownRequest))
|
||||||
@@ -533,7 +489,7 @@ func _DaemonService_GetConfig_Handler(srv interface{}, ctx context.Context, dec
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_GetConfig_FullMethodName,
|
FullMethod: "/daemon.DaemonService/GetConfig",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).GetConfig(ctx, req.(*GetConfigRequest))
|
return srv.(DaemonServiceServer).GetConfig(ctx, req.(*GetConfigRequest))
|
||||||
@@ -551,7 +507,7 @@ func _DaemonService_ListNetworks_Handler(srv interface{}, ctx context.Context, d
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_ListNetworks_FullMethodName,
|
FullMethod: "/daemon.DaemonService/ListNetworks",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).ListNetworks(ctx, req.(*ListNetworksRequest))
|
return srv.(DaemonServiceServer).ListNetworks(ctx, req.(*ListNetworksRequest))
|
||||||
@@ -569,7 +525,7 @@ func _DaemonService_SelectNetworks_Handler(srv interface{}, ctx context.Context,
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_SelectNetworks_FullMethodName,
|
FullMethod: "/daemon.DaemonService/SelectNetworks",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).SelectNetworks(ctx, req.(*SelectNetworksRequest))
|
return srv.(DaemonServiceServer).SelectNetworks(ctx, req.(*SelectNetworksRequest))
|
||||||
@@ -587,7 +543,7 @@ func _DaemonService_DeselectNetworks_Handler(srv interface{}, ctx context.Contex
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_DeselectNetworks_FullMethodName,
|
FullMethod: "/daemon.DaemonService/DeselectNetworks",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).DeselectNetworks(ctx, req.(*SelectNetworksRequest))
|
return srv.(DaemonServiceServer).DeselectNetworks(ctx, req.(*SelectNetworksRequest))
|
||||||
@@ -605,7 +561,7 @@ func _DaemonService_ForwardingRules_Handler(srv interface{}, ctx context.Context
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_ForwardingRules_FullMethodName,
|
FullMethod: "/daemon.DaemonService/ForwardingRules",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).ForwardingRules(ctx, req.(*EmptyRequest))
|
return srv.(DaemonServiceServer).ForwardingRules(ctx, req.(*EmptyRequest))
|
||||||
@@ -623,7 +579,7 @@ func _DaemonService_DebugBundle_Handler(srv interface{}, ctx context.Context, de
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_DebugBundle_FullMethodName,
|
FullMethod: "/daemon.DaemonService/DebugBundle",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).DebugBundle(ctx, req.(*DebugBundleRequest))
|
return srv.(DaemonServiceServer).DebugBundle(ctx, req.(*DebugBundleRequest))
|
||||||
@@ -641,7 +597,7 @@ func _DaemonService_GetLogLevel_Handler(srv interface{}, ctx context.Context, de
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_GetLogLevel_FullMethodName,
|
FullMethod: "/daemon.DaemonService/GetLogLevel",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).GetLogLevel(ctx, req.(*GetLogLevelRequest))
|
return srv.(DaemonServiceServer).GetLogLevel(ctx, req.(*GetLogLevelRequest))
|
||||||
@@ -659,7 +615,7 @@ func _DaemonService_SetLogLevel_Handler(srv interface{}, ctx context.Context, de
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_SetLogLevel_FullMethodName,
|
FullMethod: "/daemon.DaemonService/SetLogLevel",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).SetLogLevel(ctx, req.(*SetLogLevelRequest))
|
return srv.(DaemonServiceServer).SetLogLevel(ctx, req.(*SetLogLevelRequest))
|
||||||
@@ -677,7 +633,7 @@ func _DaemonService_ListStates_Handler(srv interface{}, ctx context.Context, dec
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_ListStates_FullMethodName,
|
FullMethod: "/daemon.DaemonService/ListStates",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).ListStates(ctx, req.(*ListStatesRequest))
|
return srv.(DaemonServiceServer).ListStates(ctx, req.(*ListStatesRequest))
|
||||||
@@ -695,7 +651,7 @@ func _DaemonService_CleanState_Handler(srv interface{}, ctx context.Context, dec
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_CleanState_FullMethodName,
|
FullMethod: "/daemon.DaemonService/CleanState",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).CleanState(ctx, req.(*CleanStateRequest))
|
return srv.(DaemonServiceServer).CleanState(ctx, req.(*CleanStateRequest))
|
||||||
@@ -713,7 +669,7 @@ func _DaemonService_DeleteState_Handler(srv interface{}, ctx context.Context, de
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_DeleteState_FullMethodName,
|
FullMethod: "/daemon.DaemonService/DeleteState",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).DeleteState(ctx, req.(*DeleteStateRequest))
|
return srv.(DaemonServiceServer).DeleteState(ctx, req.(*DeleteStateRequest))
|
||||||
@@ -731,7 +687,7 @@ func _DaemonService_SetNetworkMapPersistence_Handler(srv interface{}, ctx contex
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_SetNetworkMapPersistence_FullMethodName,
|
FullMethod: "/daemon.DaemonService/SetNetworkMapPersistence",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).SetNetworkMapPersistence(ctx, req.(*SetNetworkMapPersistenceRequest))
|
return srv.(DaemonServiceServer).SetNetworkMapPersistence(ctx, req.(*SetNetworkMapPersistenceRequest))
|
||||||
@@ -749,7 +705,7 @@ func _DaemonService_TracePacket_Handler(srv interface{}, ctx context.Context, de
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_TracePacket_FullMethodName,
|
FullMethod: "/daemon.DaemonService/TracePacket",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).TracePacket(ctx, req.(*TracePacketRequest))
|
return srv.(DaemonServiceServer).TracePacket(ctx, req.(*TracePacketRequest))
|
||||||
@@ -762,11 +718,21 @@ func _DaemonService_SubscribeEvents_Handler(srv interface{}, stream grpc.ServerS
|
|||||||
if err := stream.RecvMsg(m); err != nil {
|
if err := stream.RecvMsg(m); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return srv.(DaemonServiceServer).SubscribeEvents(m, &grpc.GenericServerStream[SubscribeRequest, SystemEvent]{ServerStream: stream})
|
return srv.(DaemonServiceServer).SubscribeEvents(m, &daemonServiceSubscribeEventsServer{stream})
|
||||||
}
|
}
|
||||||
|
|
||||||
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
|
type DaemonService_SubscribeEventsServer interface {
|
||||||
type DaemonService_SubscribeEventsServer = grpc.ServerStreamingServer[SystemEvent]
|
Send(*SystemEvent) error
|
||||||
|
grpc.ServerStream
|
||||||
|
}
|
||||||
|
|
||||||
|
type daemonServiceSubscribeEventsServer struct {
|
||||||
|
grpc.ServerStream
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *daemonServiceSubscribeEventsServer) Send(m *SystemEvent) error {
|
||||||
|
return x.ServerStream.SendMsg(m)
|
||||||
|
}
|
||||||
|
|
||||||
func _DaemonService_GetEvents_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
func _DaemonService_GetEvents_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
in := new(GetEventsRequest)
|
in := new(GetEventsRequest)
|
||||||
@@ -778,7 +744,7 @@ func _DaemonService_GetEvents_Handler(srv interface{}, ctx context.Context, dec
|
|||||||
}
|
}
|
||||||
info := &grpc.UnaryServerInfo{
|
info := &grpc.UnaryServerInfo{
|
||||||
Server: srv,
|
Server: srv,
|
||||||
FullMethod: DaemonService_GetEvents_FullMethodName,
|
FullMethod: "/daemon.DaemonService/GetEvents",
|
||||||
}
|
}
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
return srv.(DaemonServiceServer).GetEvents(ctx, req.(*GetEventsRequest))
|
return srv.(DaemonServiceServer).GetEvents(ctx, req.(*GetEventsRequest))
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ fi
|
|||||||
old_pwd=$(pwd)
|
old_pwd=$(pwd)
|
||||||
script_path=$(dirname $(realpath "$0"))
|
script_path=$(dirname $(realpath "$0"))
|
||||||
cd "$script_path"
|
cd "$script_path"
|
||||||
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26
|
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.36.6
|
||||||
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1
|
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1
|
||||||
protoc -I ./ ./daemon.proto --go_out=../ --go-grpc_out=../ --experimental_allow_proto3_optional
|
protoc -I ./ ./daemon.proto --go_out=../ --go-grpc_out=../ --experimental_allow_proto3_optional
|
||||||
cd "$old_pwd"
|
cd "$old_pwd"
|
||||||
@@ -42,6 +42,7 @@ func (s *Server) DebugBundle(_ context.Context, req *proto.DebugBundleRequest) (
|
|||||||
Anonymize: req.GetAnonymize(),
|
Anonymize: req.GetAnonymize(),
|
||||||
ClientStatus: req.GetStatus(),
|
ClientStatus: req.GetStatus(),
|
||||||
IncludeSystemInfo: req.GetSystemInfo(),
|
IncludeSystemInfo: req.GetSystemInfo(),
|
||||||
|
LogFileCount: req.GetLogFileCount(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -25,7 +25,7 @@ require (
|
|||||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6
|
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6
|
||||||
golang.zx2c4.com/wireguard/windows v0.5.3
|
golang.zx2c4.com/wireguard/windows v0.5.3
|
||||||
google.golang.org/grpc v1.64.1
|
google.golang.org/grpc v1.64.1
|
||||||
google.golang.org/protobuf v1.36.5
|
google.golang.org/protobuf v1.36.6
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -1164,8 +1164,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
|
|||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|||||||
@@ -87,6 +87,12 @@ func startManagement(t *testing.T) (*grpc.Server, net.Listener) {
|
|||||||
).
|
).
|
||||||
Return(&types.Settings{}, nil).
|
Return(&types.Settings{}, nil).
|
||||||
AnyTimes()
|
AnyTimes()
|
||||||
|
settingsMockManager.
|
||||||
|
EXPECT().
|
||||||
|
GetExtraSettings(gomock.Any(), gomock.Any()).
|
||||||
|
Return(&types.ExtraSettings{}, nil).
|
||||||
|
AnyTimes()
|
||||||
|
|
||||||
permissionsManagerMock := permissions.NewMockManager(ctrl)
|
permissionsManagerMock := permissions.NewMockManager(ctrl)
|
||||||
permissionsManagerMock.
|
permissionsManagerMock.
|
||||||
EXPECT().
|
EXPECT().
|
||||||
|
|||||||
@@ -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, 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), nil)
|
||||||
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, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ func (c *Client) initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewRequest creates and executes new management API request
|
// NewRequest creates and executes new management API request
|
||||||
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, query map[string]string) (*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
|
||||||
@@ -129,6 +129,14 @@ 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")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(query) != 0 {
|
||||||
|
q := req.URL.Query()
|
||||||
|
for k, v := range query {
|
||||||
|
q.Add(k, v)
|
||||||
|
}
|
||||||
|
req.URL.RawQuery = q.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
resp, err := c.httpClient.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, 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, 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), nil)
|
||||||
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), nil)
|
||||||
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, 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, 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), nil)
|
||||||
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, 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, 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, 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, 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, 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), nil)
|
||||||
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), nil)
|
||||||
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, 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, 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, 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), nil)
|
||||||
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), nil)
|
||||||
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, 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, 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, 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), nil)
|
||||||
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), nil)
|
||||||
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, 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, 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, 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), nil)
|
||||||
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), nil)
|
||||||
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, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,30 @@ type PeersAPI struct {
|
|||||||
c *Client
|
c *Client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PeersListOption options for Peers List API
|
||||||
|
type PeersListOption func() (string, string)
|
||||||
|
|
||||||
|
func PeerNameFilter(name string) PeersListOption {
|
||||||
|
return func() (string, string) {
|
||||||
|
return "name", name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func PeerIPFilter(ip string) PeersListOption {
|
||||||
|
return func() (string, string) {
|
||||||
|
return "ip", ip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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, opts ...PeersListOption) ([]api.Peer, error) {
|
||||||
resp, err := a.c.NewRequest(ctx, "GET", "/api/peers", nil)
|
query := make(map[string]string)
|
||||||
|
for _, o := range opts {
|
||||||
|
k, v := o()
|
||||||
|
query[k] = v
|
||||||
|
}
|
||||||
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/peers", nil, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +50,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, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +68,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), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -62,7 +82,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, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -76,7 +96,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, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,6 +184,10 @@ func TestPeers_Integration(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotEmpty(t, peers)
|
require.NotEmpty(t, peers)
|
||||||
|
|
||||||
|
filteredPeers, err := c.Peers.List(context.Background(), rest.PeerIPFilter("192.168.10.0"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Empty(t, filteredPeers)
|
||||||
|
|
||||||
peer, err := c.Peers.Get(context.Background(), peers[0].Id)
|
peer, err := c.Peers.Get(context.Background(), peers[0].Id)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, peers[0].Id, peer.Id)
|
assert.Equal(t, peers[0].Id, peer.Id)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ type PoliciesAPI struct {
|
|||||||
func (a *PoliciesAPI) List(ctx context.Context) ([]api.Policy, error) {
|
func (a *PoliciesAPI) List(ctx context.Context) ([]api.Policy, error) {
|
||||||
path := "/api/policies"
|
path := "/api/policies"
|
||||||
|
|
||||||
resp, err := a.c.NewRequest(ctx, "GET", path, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", path, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -32,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, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -50,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), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ func (a *PoliciesAPI) Update(ctx context.Context, policyID string, request api.P
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.NewRequest(ctx, "PUT", path, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", path, bytes.NewReader(requestBytes), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -84,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, 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, 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, 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), nil)
|
||||||
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), nil)
|
||||||
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, 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, 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, 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), nil)
|
||||||
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), nil)
|
||||||
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, 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, 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, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ func (a *SetupKeysAPI) Create(ctx context.Context, request api.PostApiSetupKeysJ
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.NewRequest(ctx, "POST", path, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", path, bytes.NewReader(requestBytes), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -68,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), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -82,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, 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, 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, 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), nil)
|
||||||
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, 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, 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), nil)
|
||||||
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), nil)
|
||||||
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, 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, 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, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ type Manager interface {
|
|||||||
GetAccountSettings(ctx context.Context, accountID string, userID string) (*types.Settings, error)
|
GetAccountSettings(ctx context.Context, accountID string, userID string) (*types.Settings, error)
|
||||||
DeleteSetupKey(ctx context.Context, accountID, userID, keyID string) error
|
DeleteSetupKey(ctx context.Context, accountID, userID, keyID string) error
|
||||||
UpdateAccountPeers(ctx context.Context, accountID string)
|
UpdateAccountPeers(ctx context.Context, accountID string)
|
||||||
|
BufferUpdateAccountPeers(ctx context.Context, accountID string)
|
||||||
BuildUserInfosForAccount(ctx context.Context, accountID, initiatorUserID string, accountUsers []*types.User) (map[string]*types.UserInfo, error)
|
BuildUserInfosForAccount(ctx context.Context, accountID, initiatorUserID string, accountUsers []*types.User) (map[string]*types.UserInfo, error)
|
||||||
SyncUserJWTGroups(ctx context.Context, userAuth nbcontext.UserAuth) error
|
SyncUserJWTGroups(ctx context.Context, userAuth nbcontext.UserAuth) error
|
||||||
GetStore() store.Store
|
GetStore() store.Store
|
||||||
|
|||||||
@@ -216,6 +216,8 @@ func createDNSManager(t *testing.T) (*DefaultAccountManager, error) {
|
|||||||
t.Cleanup(ctrl.Finish)
|
t.Cleanup(ctrl.Finish)
|
||||||
|
|
||||||
settingsMockManager := settings.NewMockManager(ctrl)
|
settingsMockManager := settings.NewMockManager(ctrl)
|
||||||
|
// return empty extra settings for expected calls to UpdateAccountPeers
|
||||||
|
settingsMockManager.EXPECT().GetExtraSettings(gomock.Any(), gomock.Any()).Return(&types.ExtraSettings{}, nil).AnyTimes()
|
||||||
permissionsManager := permissions.NewManager(store)
|
permissionsManager := permissions.NewManager(store)
|
||||||
return BuildManager(context.Background(), store, NewPeersUpdateManager(nil), nil, "", "netbird.test", eventStore, nil, false, MocIntegratedValidator{}, metrics, port_forwarding.NewControllerMock(), settingsMockManager, permissionsManager, false)
|
return BuildManager(context.Background(), store, NewPeersUpdateManager(nil), nil, "", "netbird.test", eventStore, nil, false, MocIntegratedValidator{}, metrics, port_forwarding.NewControllerMock(), settingsMockManager, permissionsManager, false)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
ephemeralLifeTime = 10 * time.Minute
|
ephemeralLifeTime = 10 * time.Minute
|
||||||
|
// cleanupWindow is the time window to wait after nearest peer deadline to start the cleanup procedure.
|
||||||
|
cleanupWindow = 1 * time.Minute
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -41,6 +43,9 @@ type EphemeralManager struct {
|
|||||||
tailPeer *ephemeralPeer
|
tailPeer *ephemeralPeer
|
||||||
peersLock sync.Mutex
|
peersLock sync.Mutex
|
||||||
timer *time.Timer
|
timer *time.Timer
|
||||||
|
|
||||||
|
lifeTime time.Duration
|
||||||
|
cleanupWindow time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEphemeralManager instantiate new EphemeralManager
|
// NewEphemeralManager instantiate new EphemeralManager
|
||||||
@@ -48,6 +53,9 @@ func NewEphemeralManager(store store.Store, accountManager nbAccount.Manager) *E
|
|||||||
return &EphemeralManager{
|
return &EphemeralManager{
|
||||||
store: store,
|
store: store,
|
||||||
accountManager: accountManager,
|
accountManager: accountManager,
|
||||||
|
|
||||||
|
lifeTime: ephemeralLifeTime,
|
||||||
|
cleanupWindow: cleanupWindow,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +68,7 @@ func (e *EphemeralManager) LoadInitialPeers(ctx context.Context) {
|
|||||||
|
|
||||||
e.loadEphemeralPeers(ctx)
|
e.loadEphemeralPeers(ctx)
|
||||||
if e.headPeer != nil {
|
if e.headPeer != nil {
|
||||||
e.timer = time.AfterFunc(ephemeralLifeTime, func() {
|
e.timer = time.AfterFunc(e.lifeTime, func() {
|
||||||
e.cleanup(ctx)
|
e.cleanup(ctx)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -113,9 +121,13 @@ func (e *EphemeralManager) OnPeerDisconnected(ctx context.Context, peer *nbpeer.
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
e.addPeer(peer.AccountID, peer.ID, newDeadLine())
|
e.addPeer(peer.AccountID, peer.ID, e.newDeadLine())
|
||||||
if e.timer == nil {
|
if e.timer == nil {
|
||||||
e.timer = time.AfterFunc(e.headPeer.deadline.Sub(timeNow()), func() {
|
delay := e.headPeer.deadline.Sub(timeNow()) + e.cleanupWindow
|
||||||
|
if delay < 0 {
|
||||||
|
delay = 0
|
||||||
|
}
|
||||||
|
e.timer = time.AfterFunc(delay, func() {
|
||||||
e.cleanup(ctx)
|
e.cleanup(ctx)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -128,7 +140,7 @@ func (e *EphemeralManager) loadEphemeralPeers(ctx context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
t := newDeadLine()
|
t := e.newDeadLine()
|
||||||
for _, p := range peers {
|
for _, p := range peers {
|
||||||
e.addPeer(p.AccountID, p.ID, t)
|
e.addPeer(p.AccountID, p.ID, t)
|
||||||
}
|
}
|
||||||
@@ -155,7 +167,11 @@ func (e *EphemeralManager) cleanup(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if e.headPeer != nil {
|
if e.headPeer != nil {
|
||||||
e.timer = time.AfterFunc(e.headPeer.deadline.Sub(timeNow()), func() {
|
delay := e.headPeer.deadline.Sub(timeNow()) + e.cleanupWindow
|
||||||
|
if delay < 0 {
|
||||||
|
delay = 0
|
||||||
|
}
|
||||||
|
e.timer = time.AfterFunc(delay, func() {
|
||||||
e.cleanup(ctx)
|
e.cleanup(ctx)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@@ -164,13 +180,20 @@ func (e *EphemeralManager) cleanup(ctx context.Context) {
|
|||||||
|
|
||||||
e.peersLock.Unlock()
|
e.peersLock.Unlock()
|
||||||
|
|
||||||
|
bufferAccountCall := make(map[string]struct{})
|
||||||
|
|
||||||
for id, p := range deletePeers {
|
for id, p := range deletePeers {
|
||||||
log.WithContext(ctx).Debugf("delete ephemeral peer: %s", id)
|
log.WithContext(ctx).Debugf("delete ephemeral peer: %s", id)
|
||||||
err := e.accountManager.DeletePeer(ctx, p.accountID, id, activity.SystemInitiator)
|
err := e.accountManager.DeletePeer(ctx, p.accountID, id, activity.SystemInitiator)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithContext(ctx).Errorf("failed to delete ephemeral peer: %s", err)
|
log.WithContext(ctx).Errorf("failed to delete ephemeral peer: %s", err)
|
||||||
|
} else {
|
||||||
|
bufferAccountCall[p.accountID] = struct{}{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for accountID := range bufferAccountCall {
|
||||||
|
e.accountManager.BufferUpdateAccountPeers(ctx, accountID)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *EphemeralManager) addPeer(accountID string, peerID string, deadline time.Time) {
|
func (e *EphemeralManager) addPeer(accountID string, peerID string, deadline time.Time) {
|
||||||
@@ -223,6 +246,6 @@ func (e *EphemeralManager) isPeerOnList(id string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDeadLine() time.Time {
|
func (e *EphemeralManager) newDeadLine() time.Time {
|
||||||
return timeNow().Add(ephemeralLifeTime)
|
return timeNow().Add(e.lifeTime)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,12 @@ package server
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
nbAccount "github.com/netbirdio/netbird/management/server/account"
|
nbAccount "github.com/netbirdio/netbird/management/server/account"
|
||||||
nbpeer "github.com/netbirdio/netbird/management/server/peer"
|
nbpeer "github.com/netbirdio/netbird/management/server/peer"
|
||||||
"github.com/netbirdio/netbird/management/server/store"
|
"github.com/netbirdio/netbird/management/server/store"
|
||||||
@@ -27,28 +30,65 @@ func (s *MockStore) GetAllEphemeralPeers(_ context.Context, _ store.LockingStren
|
|||||||
return peers, nil
|
return peers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type MocAccountManager struct {
|
type MockAccountManager struct {
|
||||||
|
mu sync.Mutex
|
||||||
nbAccount.Manager
|
nbAccount.Manager
|
||||||
store *MockStore
|
store *MockStore
|
||||||
|
deletePeerCalls int
|
||||||
|
bufferUpdateCalls map[string]int
|
||||||
|
wg *sync.WaitGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a MocAccountManager) DeletePeer(_ context.Context, accountID, peerID, userID string) error {
|
func (a *MockAccountManager) DeletePeer(_ context.Context, accountID, peerID, userID string) error {
|
||||||
|
a.mu.Lock()
|
||||||
|
defer a.mu.Unlock()
|
||||||
|
a.deletePeerCalls++
|
||||||
|
if a.wg != nil {
|
||||||
|
a.wg.Done()
|
||||||
|
}
|
||||||
delete(a.store.account.Peers, peerID)
|
delete(a.store.account.Peers, peerID)
|
||||||
return nil //nolint:nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a MocAccountManager) GetStore() store.Store {
|
func (a *MockAccountManager) GetDeletePeerCalls() int {
|
||||||
|
a.mu.Lock()
|
||||||
|
defer a.mu.Unlock()
|
||||||
|
return a.deletePeerCalls
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *MockAccountManager) BufferUpdateAccountPeers(ctx context.Context, accountID string) {
|
||||||
|
a.mu.Lock()
|
||||||
|
defer a.mu.Unlock()
|
||||||
|
if a.bufferUpdateCalls == nil {
|
||||||
|
a.bufferUpdateCalls = make(map[string]int)
|
||||||
|
}
|
||||||
|
a.bufferUpdateCalls[accountID]++
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *MockAccountManager) GetBufferUpdateCalls(accountID string) int {
|
||||||
|
a.mu.Lock()
|
||||||
|
defer a.mu.Unlock()
|
||||||
|
if a.bufferUpdateCalls == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return a.bufferUpdateCalls[accountID]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *MockAccountManager) GetStore() store.Store {
|
||||||
return a.store
|
return a.store
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewManager(t *testing.T) {
|
func TestNewManager(t *testing.T) {
|
||||||
|
t.Cleanup(func() {
|
||||||
|
timeNow = time.Now
|
||||||
|
})
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
timeNow = func() time.Time {
|
timeNow = func() time.Time {
|
||||||
return startTime
|
return startTime
|
||||||
}
|
}
|
||||||
|
|
||||||
store := &MockStore{}
|
store := &MockStore{}
|
||||||
am := MocAccountManager{
|
am := MockAccountManager{
|
||||||
store: store,
|
store: store,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +96,7 @@ func TestNewManager(t *testing.T) {
|
|||||||
numberOfEphemeralPeers := 3
|
numberOfEphemeralPeers := 3
|
||||||
seedPeers(store, numberOfPeers, numberOfEphemeralPeers)
|
seedPeers(store, numberOfPeers, numberOfEphemeralPeers)
|
||||||
|
|
||||||
mgr := NewEphemeralManager(store, am)
|
mgr := NewEphemeralManager(store, &am)
|
||||||
mgr.loadEphemeralPeers(context.Background())
|
mgr.loadEphemeralPeers(context.Background())
|
||||||
startTime = startTime.Add(ephemeralLifeTime + 1)
|
startTime = startTime.Add(ephemeralLifeTime + 1)
|
||||||
mgr.cleanup(context.Background())
|
mgr.cleanup(context.Background())
|
||||||
@@ -67,13 +107,16 @@ func TestNewManager(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNewManagerPeerConnected(t *testing.T) {
|
func TestNewManagerPeerConnected(t *testing.T) {
|
||||||
|
t.Cleanup(func() {
|
||||||
|
timeNow = time.Now
|
||||||
|
})
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
timeNow = func() time.Time {
|
timeNow = func() time.Time {
|
||||||
return startTime
|
return startTime
|
||||||
}
|
}
|
||||||
|
|
||||||
store := &MockStore{}
|
store := &MockStore{}
|
||||||
am := MocAccountManager{
|
am := MockAccountManager{
|
||||||
store: store,
|
store: store,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +124,7 @@ func TestNewManagerPeerConnected(t *testing.T) {
|
|||||||
numberOfEphemeralPeers := 3
|
numberOfEphemeralPeers := 3
|
||||||
seedPeers(store, numberOfPeers, numberOfEphemeralPeers)
|
seedPeers(store, numberOfPeers, numberOfEphemeralPeers)
|
||||||
|
|
||||||
mgr := NewEphemeralManager(store, am)
|
mgr := NewEphemeralManager(store, &am)
|
||||||
mgr.loadEphemeralPeers(context.Background())
|
mgr.loadEphemeralPeers(context.Background())
|
||||||
mgr.OnPeerConnected(context.Background(), store.account.Peers["ephemeral_peer_0"])
|
mgr.OnPeerConnected(context.Background(), store.account.Peers["ephemeral_peer_0"])
|
||||||
|
|
||||||
@@ -95,13 +138,16 @@ func TestNewManagerPeerConnected(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNewManagerPeerDisconnected(t *testing.T) {
|
func TestNewManagerPeerDisconnected(t *testing.T) {
|
||||||
|
t.Cleanup(func() {
|
||||||
|
timeNow = time.Now
|
||||||
|
})
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
timeNow = func() time.Time {
|
timeNow = func() time.Time {
|
||||||
return startTime
|
return startTime
|
||||||
}
|
}
|
||||||
|
|
||||||
store := &MockStore{}
|
store := &MockStore{}
|
||||||
am := MocAccountManager{
|
am := MockAccountManager{
|
||||||
store: store,
|
store: store,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,7 +155,7 @@ func TestNewManagerPeerDisconnected(t *testing.T) {
|
|||||||
numberOfEphemeralPeers := 3
|
numberOfEphemeralPeers := 3
|
||||||
seedPeers(store, numberOfPeers, numberOfEphemeralPeers)
|
seedPeers(store, numberOfPeers, numberOfEphemeralPeers)
|
||||||
|
|
||||||
mgr := NewEphemeralManager(store, am)
|
mgr := NewEphemeralManager(store, &am)
|
||||||
mgr.loadEphemeralPeers(context.Background())
|
mgr.loadEphemeralPeers(context.Background())
|
||||||
for _, v := range store.account.Peers {
|
for _, v := range store.account.Peers {
|
||||||
mgr.OnPeerConnected(context.Background(), v)
|
mgr.OnPeerConnected(context.Background(), v)
|
||||||
@@ -126,6 +172,36 @@ func TestNewManagerPeerDisconnected(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCleanupSchedulingBehaviorIsBatched(t *testing.T) {
|
||||||
|
const (
|
||||||
|
ephemeralPeers = 10
|
||||||
|
testLifeTime = 1 * time.Second
|
||||||
|
testCleanupWindow = 100 * time.Millisecond
|
||||||
|
)
|
||||||
|
mockStore := &MockStore{}
|
||||||
|
mockAM := &MockAccountManager{
|
||||||
|
store: mockStore,
|
||||||
|
}
|
||||||
|
mockAM.wg = &sync.WaitGroup{}
|
||||||
|
mockAM.wg.Add(ephemeralPeers)
|
||||||
|
mgr := NewEphemeralManager(mockStore, mockAM)
|
||||||
|
mgr.lifeTime = testLifeTime
|
||||||
|
mgr.cleanupWindow = testCleanupWindow
|
||||||
|
|
||||||
|
account := newAccountWithId(context.Background(), "account", "", "", false)
|
||||||
|
mockStore.account = account
|
||||||
|
for i := range ephemeralPeers {
|
||||||
|
p := &nbpeer.Peer{ID: fmt.Sprintf("peer-%d", i), AccountID: account.Id, Ephemeral: true}
|
||||||
|
mockStore.account.Peers[p.ID] = p
|
||||||
|
time.Sleep(testCleanupWindow / ephemeralPeers)
|
||||||
|
mgr.OnPeerDisconnected(context.Background(), p)
|
||||||
|
}
|
||||||
|
mockAM.wg.Wait()
|
||||||
|
assert.Len(t, mockStore.account.Peers, 0, "all ephemeral peers should be cleaned up after the lifetime")
|
||||||
|
assert.Equal(t, 1, mockAM.GetBufferUpdateCalls(account.Id), "buffer update should be called once")
|
||||||
|
assert.Equal(t, ephemeralPeers, mockAM.GetDeletePeerCalls(), "should have deleted all peers")
|
||||||
|
}
|
||||||
|
|
||||||
func seedPeers(store *MockStore, numberOfPeers int, numberOfEphemeralPeers int) {
|
func seedPeers(store *MockStore, numberOfPeers int, numberOfEphemeralPeers int) {
|
||||||
store.account = newAccountWithId(context.Background(), "my account", "", "", false)
|
store.account = newAccountWithId(context.Background(), "my account", "", "", false)
|
||||||
|
|
||||||
|
|||||||
@@ -440,7 +440,11 @@ func startManagementForTest(t *testing.T, testFile string, config *types.Config)
|
|||||||
GetSettings(gomock.Any(), gomock.Any(), gomock.Any()).
|
GetSettings(gomock.Any(), gomock.Any(), gomock.Any()).
|
||||||
AnyTimes().
|
AnyTimes().
|
||||||
Return(&types.Settings{}, nil)
|
Return(&types.Settings{}, nil)
|
||||||
|
settingsMockManager.
|
||||||
|
EXPECT().
|
||||||
|
GetExtraSettings(gomock.Any(), gomock.Any()).
|
||||||
|
Return(&types.ExtraSettings{}, nil).
|
||||||
|
AnyTimes()
|
||||||
permissionsManager := permissions.NewManager(store)
|
permissionsManager := permissions.NewManager(store)
|
||||||
|
|
||||||
accountManager, err := BuildManager(ctx, store, peersUpdateManager, nil, "", "netbird.selfhosted",
|
accountManager, err := BuildManager(ctx, store, peersUpdateManager, nil, "", "netbird.selfhosted",
|
||||||
|
|||||||
@@ -120,10 +120,20 @@ type MockAccountManager struct {
|
|||||||
GetAccountOnboardingFunc func(ctx context.Context, accountID, userID string) (*types.AccountOnboarding, error)
|
GetAccountOnboardingFunc func(ctx context.Context, accountID, userID string) (*types.AccountOnboarding, error)
|
||||||
UpdateAccountOnboardingFunc func(ctx context.Context, accountID, userID string, onboarding *types.AccountOnboarding) (*types.AccountOnboarding, error)
|
UpdateAccountOnboardingFunc func(ctx context.Context, accountID, userID string, onboarding *types.AccountOnboarding) (*types.AccountOnboarding, error)
|
||||||
GetOrCreateAccountByPrivateDomainFunc func(ctx context.Context, initiatorId, domain string) (*types.Account, bool, error)
|
GetOrCreateAccountByPrivateDomainFunc func(ctx context.Context, initiatorId, domain string) (*types.Account, bool, error)
|
||||||
|
UpdateAccountPeersFunc func(ctx context.Context, accountID string)
|
||||||
|
BufferUpdateAccountPeersFunc func(ctx context.Context, accountID string)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *MockAccountManager) UpdateAccountPeers(ctx context.Context, accountID string) {
|
func (am *MockAccountManager) UpdateAccountPeers(ctx context.Context, accountID string) {
|
||||||
// do nothing
|
if am.UpdateAccountPeersFunc != nil {
|
||||||
|
am.UpdateAccountPeersFunc(ctx, accountID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (am *MockAccountManager) BufferUpdateAccountPeers(ctx context.Context, accountID string) {
|
||||||
|
if am.BufferUpdateAccountPeersFunc != nil {
|
||||||
|
am.BufferUpdateAccountPeersFunc(ctx, accountID)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *MockAccountManager) DeleteSetupKey(ctx context.Context, accountID, userID, keyID string) error {
|
func (am *MockAccountManager) DeleteSetupKey(ctx context.Context, accountID, userID, keyID string) error {
|
||||||
|
|||||||
@@ -778,6 +778,12 @@ func createNSManager(t *testing.T) (*DefaultAccountManager, error) {
|
|||||||
ctrl := gomock.NewController(t)
|
ctrl := gomock.NewController(t)
|
||||||
t.Cleanup(ctrl.Finish)
|
t.Cleanup(ctrl.Finish)
|
||||||
settingsMockManager := settings.NewMockManager(ctrl)
|
settingsMockManager := settings.NewMockManager(ctrl)
|
||||||
|
settingsMockManager.
|
||||||
|
EXPECT().
|
||||||
|
GetExtraSettings(gomock.Any(), gomock.Any()).
|
||||||
|
Return(&types.ExtraSettings{}, nil).
|
||||||
|
AnyTimes()
|
||||||
|
|
||||||
permissionsManager := permissions.NewManager(store)
|
permissionsManager := permissions.NewManager(store)
|
||||||
return BuildManager(context.Background(), store, NewPeersUpdateManager(nil), nil, "", "netbird.selfhosted", eventStore, nil, false, MocIntegratedValidator{}, metrics, port_forwarding.NewControllerMock(), settingsMockManager, permissionsManager, false)
|
return BuildManager(context.Background(), store, NewPeersUpdateManager(nil), nil, "", "netbird.selfhosted", eventStore, nil, false, MocIntegratedValidator{}, metrics, port_forwarding.NewControllerMock(), settingsMockManager, permissionsManager, false)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/rs/xid"
|
"github.com/rs/xid"
|
||||||
@@ -236,11 +237,23 @@ func (am *DefaultAccountManager) UpdatePeer(ctx context.Context, accountID, user
|
|||||||
|
|
||||||
if peer.Name != update.Name {
|
if peer.Name != update.Name {
|
||||||
var newLabel string
|
var newLabel string
|
||||||
newLabel, err = getPeerIPDNSLabel(ctx, transaction, peer.IP, accountID, update.Name)
|
|
||||||
|
newLabel, err = nbdns.GetParsedDomainLabel(update.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get free DNS label: %w", err)
|
newLabel = ""
|
||||||
|
} else {
|
||||||
|
_, err := transaction.GetPeerIdByLabel(ctx, store.LockingStrengthNone, accountID, update.Name)
|
||||||
|
if err == nil {
|
||||||
|
newLabel = ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if newLabel == "" {
|
||||||
|
newLabel, err = getPeerIPDNSLabel(peer.IP, update.Name)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get free DNS label: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
peer.Name = update.Name
|
peer.Name = update.Name
|
||||||
peer.DNSLabel = newLabel
|
peer.DNSLabel = newLabel
|
||||||
peerLabelChanged = true
|
peerLabelChanged = true
|
||||||
@@ -364,19 +377,6 @@ func (am *DefaultAccountManager) DeletePeer(ctx context.Context, accountID, peer
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
groups, err := transaction.GetPeerGroups(ctx, store.LockingStrengthUpdate, accountID, peerID)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to get peer groups: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, group := range groups {
|
|
||||||
group.RemovePeer(peerID)
|
|
||||||
err = transaction.SaveGroup(ctx, store.LockingStrengthUpdate, group)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to save group: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eventsToStore, err = deletePeers(ctx, am, transaction, accountID, userID, []*nbpeer.Peer{peer})
|
eventsToStore, err = deletePeers(ctx, am, transaction, accountID, userID, []*nbpeer.Peer{peer})
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
@@ -388,7 +388,7 @@ func (am *DefaultAccountManager) DeletePeer(ctx context.Context, accountID, peer
|
|||||||
storeEvent()
|
storeEvent()
|
||||||
}
|
}
|
||||||
|
|
||||||
if updateAccountPeers {
|
if updateAccountPeers && userID != activity.SystemInitiator {
|
||||||
am.BufferUpdateAccountPeers(ctx, accountID)
|
am.BufferUpdateAccountPeers(ctx, accountID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,6 +485,7 @@ func (am *DefaultAccountManager) AddPeer(ctx context.Context, setupKey, userID s
|
|||||||
var groupsToAdd []string
|
var groupsToAdd []string
|
||||||
var allowExtraDNSLabels bool
|
var allowExtraDNSLabels bool
|
||||||
var accountID string
|
var accountID string
|
||||||
|
var isEphemeral bool
|
||||||
if addedByUser {
|
if addedByUser {
|
||||||
user, err := am.Store.GetUserByUserID(ctx, store.LockingStrengthNone, userID)
|
user, err := am.Store.GetUserByUserID(ctx, store.LockingStrengthNone, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -514,7 +515,7 @@ func (am *DefaultAccountManager) AddPeer(ctx context.Context, setupKey, userID s
|
|||||||
setupKeyName = sk.Name
|
setupKeyName = sk.Name
|
||||||
allowExtraDNSLabels = sk.AllowExtraDNSLabels
|
allowExtraDNSLabels = sk.AllowExtraDNSLabels
|
||||||
accountID = sk.AccountID
|
accountID = sk.AccountID
|
||||||
|
isEphemeral = sk.Ephemeral
|
||||||
if !sk.AllowExtraDNSLabels && len(peer.ExtraDNSLabels) > 0 {
|
if !sk.AllowExtraDNSLabels && len(peer.ExtraDNSLabels) > 0 {
|
||||||
return nil, nil, nil, status.Errorf(status.PreconditionFailed, "couldn't add peer: setup key doesn't allow extra DNS labels")
|
return nil, nil, nil, status.Errorf(status.PreconditionFailed, "couldn't add peer: setup key doesn't allow extra DNS labels")
|
||||||
}
|
}
|
||||||
@@ -586,11 +587,17 @@ func (am *DefaultAccountManager) AddPeer(ctx context.Context, setupKey, userID s
|
|||||||
}
|
}
|
||||||
|
|
||||||
var freeLabel string
|
var freeLabel string
|
||||||
freeLabel, err = getPeerIPDNSLabel(ctx, am.Store, freeIP, accountID, peer.Meta.Hostname)
|
if isEphemeral || attempt > 1 {
|
||||||
if err != nil {
|
freeLabel, err = getPeerIPDNSLabel(freeIP, peer.Meta.Hostname)
|
||||||
return nil, nil, nil, fmt.Errorf("failed to get free DNS label: %w", err)
|
if err != nil {
|
||||||
|
return nil, nil, nil, fmt.Errorf("failed to get free DNS label: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
freeLabel, err = nbdns.GetParsedDomainLabel(peer.Meta.Hostname)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, fmt.Errorf("failed to get free DNS label: %w", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newPeer.DNSLabel = freeLabel
|
newPeer.DNSLabel = freeLabel
|
||||||
newPeer.IP = freeIP
|
newPeer.IP = freeIP
|
||||||
|
|
||||||
@@ -660,7 +667,7 @@ func (am *DefaultAccountManager) AddPeer(ctx context.Context, setupKey, userID s
|
|||||||
if isUniqueConstraintError(err) {
|
if isUniqueConstraintError(err) {
|
||||||
unlock()
|
unlock()
|
||||||
unlock = nil
|
unlock = nil
|
||||||
log.WithContext(ctx).Debugf("Failed to add peer in attempt %d, retrying: %v", attempt, err)
|
log.WithContext(ctx).WithFields(log.Fields{"dns_label": freeLabel, "ip": freeIP}).Tracef("Failed to add peer in attempt %d, retrying: %v", attempt, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -694,7 +701,7 @@ func (am *DefaultAccountManager) AddPeer(ctx context.Context, setupKey, userID s
|
|||||||
return am.getValidatedPeerWithMap(ctx, false, accountID, newPeer)
|
return am.getValidatedPeerWithMap(ctx, false, accountID, newPeer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPeerIPDNSLabel(ctx context.Context, tx store.Store, ip net.IP, accountID, peerHostName string) (string, error) {
|
func getPeerIPDNSLabel(ip net.IP, peerHostName string) (string, error) {
|
||||||
ip = ip.To4()
|
ip = ip.To4()
|
||||||
|
|
||||||
dnsName, err := nbdns.GetParsedDomainLabel(peerHostName)
|
dnsName, err := nbdns.GetParsedDomainLabel(peerHostName)
|
||||||
@@ -702,12 +709,6 @@ func getPeerIPDNSLabel(ctx context.Context, tx store.Store, ip net.IP, accountID
|
|||||||
return "", fmt.Errorf("failed to parse peer host name %s: %w", peerHostName, err)
|
return "", fmt.Errorf("failed to parse peer host name %s: %w", peerHostName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = tx.GetPeerIdByLabel(ctx, store.LockingStrengthNone, accountID, dnsName)
|
|
||||||
if err != nil {
|
|
||||||
//nolint:nilerr
|
|
||||||
return dnsName, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("%s-%d-%d", dnsName, ip[2], ip[3]), nil
|
return fmt.Sprintf("%s-%d-%d", dnsName, ip[2], ip[3]), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1190,6 +1191,19 @@ func (am *DefaultAccountManager) UpdateAccountPeers(ctx context.Context, account
|
|||||||
|
|
||||||
globalStart := time.Now()
|
globalStart := time.Now()
|
||||||
|
|
||||||
|
hasPeersConnected := false
|
||||||
|
for _, peer := range account.Peers {
|
||||||
|
if am.peersUpdateManager.HasChannel(peer.ID) {
|
||||||
|
hasPeersConnected = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hasPeersConnected {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
approvedPeersMap, err := am.integratedPeerValidator.GetValidatedPeers(account.Id, maps.Values(account.Groups), maps.Values(account.Peers), account.Settings.Extra)
|
approvedPeersMap, err := am.integratedPeerValidator.GetValidatedPeers(account.Id, maps.Values(account.Groups), maps.Values(account.Peers), account.Settings.Extra)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithContext(ctx).Errorf("failed to send out updates to peers, failed to get validate peers: %v", err)
|
log.WithContext(ctx).Errorf("failed to send out updates to peers, failed to get validate peers: %v", err)
|
||||||
@@ -1211,6 +1225,12 @@ func (am *DefaultAccountManager) UpdateAccountPeers(ctx context.Context, account
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extraSetting, err := am.settingsManager.GetExtraSettings(ctx, accountID)
|
||||||
|
if err != nil {
|
||||||
|
log.WithContext(ctx).Errorf("failed to get flow enabled status: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for _, peer := range account.Peers {
|
for _, peer := range account.Peers {
|
||||||
if !am.peersUpdateManager.HasChannel(peer.ID) {
|
if !am.peersUpdateManager.HasChannel(peer.ID) {
|
||||||
log.WithContext(ctx).Tracef("peer %s doesn't have a channel, skipping network map update", peer.ID)
|
log.WithContext(ctx).Tracef("peer %s doesn't have a channel, skipping network map update", peer.ID)
|
||||||
@@ -1245,12 +1265,6 @@ func (am *DefaultAccountManager) UpdateAccountPeers(ctx context.Context, account
|
|||||||
}
|
}
|
||||||
am.metrics.UpdateChannelMetrics().CountMergeNetworkMapDuration(time.Since(start))
|
am.metrics.UpdateChannelMetrics().CountMergeNetworkMapDuration(time.Since(start))
|
||||||
|
|
||||||
extraSetting, err := am.settingsManager.GetExtraSettings(ctx, accountID)
|
|
||||||
if err != nil {
|
|
||||||
log.WithContext(ctx).Errorf("failed to get flow enabled status: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
start = time.Now()
|
start = time.Now()
|
||||||
update := toSyncResponse(ctx, nil, p, nil, nil, remotePeerNetworkMap, dnsDomain, postureChecks, dnsCache, account.Settings, extraSetting)
|
update := toSyncResponse(ctx, nil, p, nil, nil, remotePeerNetworkMap, dnsDomain, postureChecks, dnsCache, account.Settings, extraSetting)
|
||||||
am.metrics.UpdateChannelMetrics().CountToSyncResponseDuration(time.Since(start))
|
am.metrics.UpdateChannelMetrics().CountToSyncResponseDuration(time.Since(start))
|
||||||
@@ -1267,18 +1281,39 @@ func (am *DefaultAccountManager) UpdateAccountPeers(ctx context.Context, account
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *DefaultAccountManager) BufferUpdateAccountPeers(ctx context.Context, accountID string) {
|
type bufferUpdate struct {
|
||||||
mu, _ := am.accountUpdateLocks.LoadOrStore(accountID, &sync.Mutex{})
|
mu sync.Mutex
|
||||||
lock := mu.(*sync.Mutex)
|
next *time.Timer
|
||||||
|
update atomic.Bool
|
||||||
|
}
|
||||||
|
|
||||||
if !lock.TryLock() {
|
func (am *DefaultAccountManager) BufferUpdateAccountPeers(ctx context.Context, accountID string) {
|
||||||
|
bufUpd, _ := am.accountUpdateLocks.LoadOrStore(accountID, &bufferUpdate{})
|
||||||
|
b := bufUpd.(*bufferUpdate)
|
||||||
|
|
||||||
|
if !b.mu.TryLock() {
|
||||||
|
b.update.Store(true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if b.next != nil {
|
||||||
|
b.next.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
time.Sleep(time.Duration(am.updateAccountPeersBufferInterval.Load()))
|
defer b.mu.Unlock()
|
||||||
lock.Unlock()
|
|
||||||
am.UpdateAccountPeers(ctx, accountID)
|
am.UpdateAccountPeers(ctx, accountID)
|
||||||
|
if !b.update.Load() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b.update.Store(false)
|
||||||
|
if b.next == nil {
|
||||||
|
b.next = time.AfterFunc(time.Duration(am.updateAccountPeersBufferInterval.Load()), func() {
|
||||||
|
am.UpdateAccountPeers(ctx, accountID)
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b.next.Reset(time.Duration(am.updateAccountPeersBufferInterval.Load()))
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1517,13 +1552,26 @@ func deletePeers(ctx context.Context, am *DefaultAccountManager, transaction sto
|
|||||||
}
|
}
|
||||||
dnsDomain := am.GetDNSDomain(settings)
|
dnsDomain := am.GetDNSDomain(settings)
|
||||||
|
|
||||||
|
network, err := transaction.GetAccountNetwork(ctx, store.LockingStrengthShare, accountID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
for _, peer := range peers {
|
for _, peer := range peers {
|
||||||
if err := am.integratedPeerValidator.PeerDeleted(ctx, accountID, peer.ID); err != nil {
|
groups, err := transaction.GetPeerGroups(ctx, store.LockingStrengthUpdate, accountID, peer.ID)
|
||||||
return nil, err
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to get peer groups: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
network, err := transaction.GetAccountNetwork(ctx, store.LockingStrengthShare, accountID)
|
for _, group := range groups {
|
||||||
if err != nil {
|
group.RemovePeer(peer.ID)
|
||||||
|
err = transaction.SaveGroup(ctx, store.LockingStrengthUpdate, group)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to save group: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := am.integratedPeerValidator.PeerDeleted(ctx, accountID, peer.ID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -25,6 +26,7 @@ import (
|
|||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/management/server/integrations/port_forwarding"
|
"github.com/netbirdio/netbird/management/server/integrations/port_forwarding"
|
||||||
|
"github.com/netbirdio/netbird/management/server/mock_server"
|
||||||
"github.com/netbirdio/netbird/management/server/permissions"
|
"github.com/netbirdio/netbird/management/server/permissions"
|
||||||
"github.com/netbirdio/netbird/management/server/settings"
|
"github.com/netbirdio/netbird/management/server/settings"
|
||||||
"github.com/netbirdio/netbird/management/server/status"
|
"github.com/netbirdio/netbird/management/server/status"
|
||||||
@@ -1344,6 +1346,11 @@ func Test_RegisterPeerBySetupKey(t *testing.T) {
|
|||||||
ctrl := gomock.NewController(t)
|
ctrl := gomock.NewController(t)
|
||||||
t.Cleanup(ctrl.Finish)
|
t.Cleanup(ctrl.Finish)
|
||||||
settingsMockManager := settings.NewMockManager(ctrl)
|
settingsMockManager := settings.NewMockManager(ctrl)
|
||||||
|
settingsMockManager.
|
||||||
|
EXPECT().
|
||||||
|
GetExtraSettings(gomock.Any(), gomock.Any()).
|
||||||
|
Return(&types.ExtraSettings{}, nil).
|
||||||
|
AnyTimes()
|
||||||
permissionsManager := permissions.NewManager(s)
|
permissionsManager := permissions.NewManager(s)
|
||||||
|
|
||||||
am, err := BuildManager(context.Background(), s, NewPeersUpdateManager(nil), nil, "", "netbird.cloud", eventStore, nil, false, MocIntegratedValidator{}, metrics, port_forwarding.NewControllerMock(), settingsMockManager, permissionsManager, false)
|
am, err := BuildManager(context.Background(), s, NewPeersUpdateManager(nil), nil, "", "netbird.cloud", eventStore, nil, false, MocIntegratedValidator{}, metrics, port_forwarding.NewControllerMock(), settingsMockManager, permissionsManager, false)
|
||||||
@@ -1556,6 +1563,11 @@ func Test_LoginPeer(t *testing.T) {
|
|||||||
ctrl := gomock.NewController(t)
|
ctrl := gomock.NewController(t)
|
||||||
t.Cleanup(ctrl.Finish)
|
t.Cleanup(ctrl.Finish)
|
||||||
settingsMockManager := settings.NewMockManager(ctrl)
|
settingsMockManager := settings.NewMockManager(ctrl)
|
||||||
|
settingsMockManager.
|
||||||
|
EXPECT().
|
||||||
|
GetExtraSettings(gomock.Any(), gomock.Any()).
|
||||||
|
Return(&types.ExtraSettings{}, nil).
|
||||||
|
AnyTimes()
|
||||||
permissionsManager := permissions.NewManager(s)
|
permissionsManager := permissions.NewManager(s)
|
||||||
|
|
||||||
am, err := BuildManager(context.Background(), s, NewPeersUpdateManager(nil), nil, "", "netbird.cloud", eventStore, nil, false, MocIntegratedValidator{}, metrics, port_forwarding.NewControllerMock(), settingsMockManager, permissionsManager, false)
|
am, err := BuildManager(context.Background(), s, NewPeersUpdateManager(nil), nil, "", "netbird.cloud", eventStore, nil, false, MocIntegratedValidator{}, metrics, port_forwarding.NewControllerMock(), settingsMockManager, permissionsManager, false)
|
||||||
@@ -2241,3 +2253,131 @@ func Test_AddPeer(t *testing.T) {
|
|||||||
assert.Equal(t, totalPeers, maps.Values(account.SetupKeys)[0].UsedTimes)
|
assert.Equal(t, totalPeers, maps.Values(account.SetupKeys)[0].UsedTimes)
|
||||||
assert.Equal(t, uint64(totalPeers), account.Network.Serial)
|
assert.Equal(t, uint64(totalPeers), account.Network.Serial)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBufferUpdateAccountPeers(t *testing.T) {
|
||||||
|
const (
|
||||||
|
peersCount = 1000
|
||||||
|
updateAccountInterval = 50 * time.Millisecond
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
deletedPeers, updatePeersDeleted, updatePeersRuns atomic.Int32
|
||||||
|
uapLastRun, dpLastRun atomic.Int64
|
||||||
|
|
||||||
|
totalNewRuns, totalOldRuns int
|
||||||
|
)
|
||||||
|
|
||||||
|
uap := func(ctx context.Context, accountID string) {
|
||||||
|
updatePeersDeleted.Store(deletedPeers.Load())
|
||||||
|
updatePeersRuns.Add(1)
|
||||||
|
uapLastRun.Store(time.Now().UnixMilli())
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("new approach", func(t *testing.T) {
|
||||||
|
updatePeersRuns.Store(0)
|
||||||
|
updatePeersDeleted.Store(0)
|
||||||
|
deletedPeers.Store(0)
|
||||||
|
|
||||||
|
var mustore sync.Map
|
||||||
|
bufupd := func(ctx context.Context, accountID string) {
|
||||||
|
mu, _ := mustore.LoadOrStore(accountID, &bufferUpdate{})
|
||||||
|
b := mu.(*bufferUpdate)
|
||||||
|
|
||||||
|
if !b.mu.TryLock() {
|
||||||
|
b.update.Store(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.next != nil {
|
||||||
|
b.next.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer b.mu.Unlock()
|
||||||
|
uap(ctx, accountID)
|
||||||
|
if !b.update.Load() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b.update.Store(false)
|
||||||
|
b.next = time.AfterFunc(updateAccountInterval, func() {
|
||||||
|
uap(ctx, accountID)
|
||||||
|
})
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
dp := func(ctx context.Context, accountID, peerID, userID string) error {
|
||||||
|
deletedPeers.Add(1)
|
||||||
|
dpLastRun.Store(time.Now().UnixMilli())
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
bufupd(ctx, accountID)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
am := mock_server.MockAccountManager{
|
||||||
|
UpdateAccountPeersFunc: uap,
|
||||||
|
BufferUpdateAccountPeersFunc: bufupd,
|
||||||
|
DeletePeerFunc: dp,
|
||||||
|
}
|
||||||
|
empty := ""
|
||||||
|
for range peersCount {
|
||||||
|
//nolint
|
||||||
|
am.DeletePeer(context.Background(), empty, empty, empty)
|
||||||
|
}
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
|
assert.Equal(t, peersCount, int(deletedPeers.Load()), "Expected all peers to be deleted")
|
||||||
|
assert.Equal(t, peersCount, int(updatePeersDeleted.Load()), "Expected all peers to be updated in the buffer")
|
||||||
|
assert.GreaterOrEqual(t, uapLastRun.Load(), dpLastRun.Load(), "Expected update account peers to run after delete peer")
|
||||||
|
|
||||||
|
totalNewRuns = int(updatePeersRuns.Load())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("old approach", func(t *testing.T) {
|
||||||
|
updatePeersRuns.Store(0)
|
||||||
|
updatePeersDeleted.Store(0)
|
||||||
|
deletedPeers.Store(0)
|
||||||
|
|
||||||
|
var mustore sync.Map
|
||||||
|
bufupd := func(ctx context.Context, accountID string) {
|
||||||
|
mu, _ := mustore.LoadOrStore(accountID, &sync.Mutex{})
|
||||||
|
b := mu.(*sync.Mutex)
|
||||||
|
|
||||||
|
if !b.TryLock() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
time.Sleep(updateAccountInterval)
|
||||||
|
b.Unlock()
|
||||||
|
uap(ctx, accountID)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
dp := func(ctx context.Context, accountID, peerID, userID string) error {
|
||||||
|
deletedPeers.Add(1)
|
||||||
|
dpLastRun.Store(time.Now().UnixMilli())
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
bufupd(ctx, accountID)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
am := mock_server.MockAccountManager{
|
||||||
|
UpdateAccountPeersFunc: uap,
|
||||||
|
BufferUpdateAccountPeersFunc: bufupd,
|
||||||
|
DeletePeerFunc: dp,
|
||||||
|
}
|
||||||
|
empty := ""
|
||||||
|
for range peersCount {
|
||||||
|
//nolint
|
||||||
|
am.DeletePeer(context.Background(), empty, empty, empty)
|
||||||
|
}
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
|
assert.Equal(t, peersCount, int(deletedPeers.Load()), "Expected all peers to be deleted")
|
||||||
|
assert.Equal(t, peersCount, int(updatePeersDeleted.Load()), "Expected all peers to be updated in the buffer")
|
||||||
|
assert.GreaterOrEqual(t, uapLastRun.Load(), dpLastRun.Load(), "Expected update account peers to run after delete peer")
|
||||||
|
|
||||||
|
totalOldRuns = int(updatePeersRuns.Load())
|
||||||
|
})
|
||||||
|
assert.Less(t, totalNewRuns, totalOldRuns, "Expected new approach to run less than old approach. New runs: %d, Old runs: %d", totalNewRuns, totalOldRuns)
|
||||||
|
t.Logf("New runs: %d, Old runs: %d", totalNewRuns, totalOldRuns)
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ var (
|
|||||||
baseWallNano int64
|
baseWallNano int64
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Time int64
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
baseWallTime = time.Now()
|
baseWallTime = time.Now()
|
||||||
baseWallNano = baseWallTime.UnixNano()
|
baseWallNano = baseWallTime.UnixNano()
|
||||||
@@ -23,7 +25,11 @@ func init() {
|
|||||||
// and using time.Since() for elapsed calculation, this avoids repeated
|
// and using time.Since() for elapsed calculation, this avoids repeated
|
||||||
// time.Now() calls and leverages Go's internal monotonic clock for
|
// time.Now() calls and leverages Go's internal monotonic clock for
|
||||||
// efficient duration measurement.
|
// efficient duration measurement.
|
||||||
func Now() int64 {
|
func Now() Time {
|
||||||
elapsed := time.Since(baseWallTime)
|
elapsed := time.Since(baseWallTime)
|
||||||
return baseWallNano + int64(elapsed)
|
return Time(baseWallNano + int64(elapsed))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Since(t Time) time.Duration {
|
||||||
|
return time.Duration(Now() - t)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
"github.com/netbirdio/netbird/formatter"
|
"github.com/netbirdio/netbird/formatter"
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultLogSize = 5
|
const defaultLogSize = 15
|
||||||
|
|
||||||
// InitLog parses and sets log-level input
|
// InitLog parses and sets log-level input
|
||||||
func InitLog(logLevel string, logPath string) error {
|
func InitLog(logLevel string, logPath string) error {
|
||||||
|
|||||||
Reference in New Issue
Block a user