Compare commits
6 Commits
test/netwo
...
feature/ba
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b02e9c3a8 | ||
|
|
eee90fbbbf | ||
|
|
85aea0a030 | ||
|
|
e41acdb9ac | ||
|
|
54dc27abec | ||
|
|
fdd7dc67c0 |
4
.github/workflows/release.yml
vendored
@@ -71,7 +71,7 @@ jobs:
|
||||
- name: Install goversioninfo
|
||||
run: go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@233067e
|
||||
- name: Generate windows syso amd64
|
||||
run: goversioninfo -icon client/ui/netbird.ico -manifest client/manifest.xml -product-name ${{ env.PRODUCT_NAME }} -copyright "${{ env.COPYRIGHT }}" -ver-major ${{ steps.semver_parser.outputs.major }} -ver-minor ${{ steps.semver_parser.outputs.minor }} -ver-patch ${{ steps.semver_parser.outputs.patch }} -ver-build 0 -file-version ${{ steps.semver_parser.outputs.fullversion }}.0 -product-version ${{ steps.semver_parser.outputs.fullversion }}.0 -o client/resources_windows_amd64.syso
|
||||
run: goversioninfo -icon client/ui/assets/netbird.ico -manifest client/manifest.xml -product-name ${{ env.PRODUCT_NAME }} -copyright "${{ env.COPYRIGHT }}" -ver-major ${{ steps.semver_parser.outputs.major }} -ver-minor ${{ steps.semver_parser.outputs.minor }} -ver-patch ${{ steps.semver_parser.outputs.patch }} -ver-build 0 -file-version ${{ steps.semver_parser.outputs.fullversion }}.0 -product-version ${{ steps.semver_parser.outputs.fullversion }}.0 -o client/resources_windows_amd64.syso
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v4
|
||||
with:
|
||||
@@ -150,7 +150,7 @@ jobs:
|
||||
- name: Install goversioninfo
|
||||
run: go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@233067e
|
||||
- name: Generate windows syso amd64
|
||||
run: goversioninfo -64 -icon client/ui/netbird.ico -manifest client/ui/manifest.xml -product-name ${{ env.PRODUCT_NAME }}-"UI" -copyright "${{ env.COPYRIGHT }}" -ver-major ${{ steps.semver_parser.outputs.major }} -ver-minor ${{ steps.semver_parser.outputs.minor }} -ver-patch ${{ steps.semver_parser.outputs.patch }} -ver-build 0 -file-version ${{ steps.semver_parser.outputs.fullversion }}.0 -product-version ${{ steps.semver_parser.outputs.fullversion }}.0 -o client/ui/resources_windows_amd64.syso
|
||||
run: goversioninfo -64 -icon client/ui/assets/netbird.ico -manifest client/ui/manifest.xml -product-name ${{ env.PRODUCT_NAME }}-"UI" -copyright "${{ env.COPYRIGHT }}" -ver-major ${{ steps.semver_parser.outputs.major }} -ver-minor ${{ steps.semver_parser.outputs.minor }} -ver-patch ${{ steps.semver_parser.outputs.patch }} -ver-build 0 -file-version ${{ steps.semver_parser.outputs.fullversion }}.0 -product-version ${{ steps.semver_parser.outputs.fullversion }}.0 -o client/ui/resources_windows_amd64.syso
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v4
|
||||
|
||||
@@ -53,9 +53,9 @@ nfpms:
|
||||
scripts:
|
||||
postinstall: "release_files/ui-post-install.sh"
|
||||
contents:
|
||||
- src: client/ui/netbird.desktop
|
||||
- src: client/ui/build/netbird.desktop
|
||||
dst: /usr/share/applications/netbird.desktop
|
||||
- src: client/ui/netbird.png
|
||||
- src: client/ui/assets/netbird.png
|
||||
dst: /usr/share/pixmaps/netbird.png
|
||||
dependencies:
|
||||
- netbird
|
||||
@@ -72,9 +72,9 @@ nfpms:
|
||||
scripts:
|
||||
postinstall: "release_files/ui-post-install.sh"
|
||||
contents:
|
||||
- src: client/ui/netbird.desktop
|
||||
- src: client/ui/build/netbird.desktop
|
||||
dst: /usr/share/applications/netbird.desktop
|
||||
- src: client/ui/netbird.png
|
||||
- src: client/ui/assets/netbird.png
|
||||
dst: /usr/share/pixmaps/netbird.png
|
||||
dependencies:
|
||||
- netbird
|
||||
|
||||
@@ -167,7 +167,7 @@ func (m *Manager) SetLegacyManagement(isLegacy bool) error {
|
||||
}
|
||||
|
||||
// Reset firewall to the default state
|
||||
func (m *Manager) Reset(stateManager *statemanager.Manager) error {
|
||||
func (m *Manager) Close(stateManager *statemanager.Manager) error {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ func TestIptablesManager(t *testing.T) {
|
||||
time.Sleep(time.Second)
|
||||
|
||||
defer func() {
|
||||
err := manager.Reset(nil)
|
||||
err := manager.Close(nil)
|
||||
require.NoError(t, err, "clear the manager state")
|
||||
|
||||
time.Sleep(time.Second)
|
||||
@@ -100,14 +100,14 @@ func TestIptablesManager(t *testing.T) {
|
||||
_, err = manager.AddPeerFiltering(nil, ip, "udp", nil, port, fw.ActionAccept, "")
|
||||
require.NoError(t, err, "failed to add rule")
|
||||
|
||||
err = manager.Reset(nil)
|
||||
err = manager.Close(nil)
|
||||
require.NoError(t, err, "failed to reset")
|
||||
|
||||
ok, err := ipv4Client.ChainExists("filter", chainNameInputRules)
|
||||
require.NoError(t, err, "failed check chain exists")
|
||||
|
||||
if ok {
|
||||
require.NoErrorf(t, err, "chain '%v' still exists after Reset", chainNameInputRules)
|
||||
require.NoErrorf(t, err, "chain '%v' still exists after Close", chainNameInputRules)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -136,7 +136,7 @@ func TestIptablesManagerIPSet(t *testing.T) {
|
||||
time.Sleep(time.Second)
|
||||
|
||||
defer func() {
|
||||
err := manager.Reset(nil)
|
||||
err := manager.Close(nil)
|
||||
require.NoError(t, err, "clear the manager state")
|
||||
|
||||
time.Sleep(time.Second)
|
||||
@@ -166,7 +166,7 @@ func TestIptablesManagerIPSet(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("reset check", func(t *testing.T) {
|
||||
err = manager.Reset(nil)
|
||||
err = manager.Close(nil)
|
||||
require.NoError(t, err, "failed to reset")
|
||||
})
|
||||
}
|
||||
@@ -204,7 +204,7 @@ func TestIptablesCreatePerformance(t *testing.T) {
|
||||
time.Sleep(time.Second)
|
||||
|
||||
defer func() {
|
||||
err := manager.Reset(nil)
|
||||
err := manager.Close(nil)
|
||||
require.NoError(t, err, "clear the manager state")
|
||||
|
||||
time.Sleep(time.Second)
|
||||
|
||||
@@ -62,7 +62,7 @@ func (s *ShutdownState) Cleanup() error {
|
||||
ipt.aclMgr.ipsetStore = s.ACLIPsetStore
|
||||
}
|
||||
|
||||
if err := ipt.Reset(nil); err != nil {
|
||||
if err := ipt.Close(nil); err != nil {
|
||||
return fmt.Errorf("reset iptables manager: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -102,8 +102,8 @@ type Manager interface {
|
||||
// SetLegacyManagement sets the legacy management mode
|
||||
SetLegacyManagement(legacy bool) error
|
||||
|
||||
// Reset firewall to the default state
|
||||
Reset(stateManager *statemanager.Manager) error
|
||||
// Close closes the firewall manager
|
||||
Close(stateManager *statemanager.Manager) error
|
||||
|
||||
// Flush the changes to firewall controller
|
||||
Flush() error
|
||||
|
||||
@@ -87,7 +87,7 @@ func (m *Manager) Init(stateManager *statemanager.Manager) error {
|
||||
// We only need to record minimal interface state for potential recreation.
|
||||
// Unlike iptables, which requires tracking individual rules, nftables maintains
|
||||
// a known state (our netbird table plus a few static rules). This allows for easy
|
||||
// cleanup using Reset() without needing to store specific rules.
|
||||
// cleanup using Close() without needing to store specific rules.
|
||||
if err := stateManager.UpdateState(&ShutdownState{
|
||||
InterfaceState: &InterfaceState{
|
||||
NameStr: m.wgIface.Name(),
|
||||
@@ -243,7 +243,7 @@ func (m *Manager) SetLegacyManagement(isLegacy bool) error {
|
||||
}
|
||||
|
||||
// Reset firewall to the default state
|
||||
func (m *Manager) Reset(stateManager *statemanager.Manager) error {
|
||||
func (m *Manager) Close(stateManager *statemanager.Manager) error {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ func TestNftablesManager(t *testing.T) {
|
||||
time.Sleep(time.Second * 3)
|
||||
|
||||
defer func() {
|
||||
err = manager.Reset(nil)
|
||||
err = manager.Close(nil)
|
||||
require.NoError(t, err, "failed to reset")
|
||||
time.Sleep(time.Second)
|
||||
}()
|
||||
@@ -162,7 +162,7 @@ func TestNftablesManager(t *testing.T) {
|
||||
// established rule remains
|
||||
require.Len(t, rules, 1, "expected 1 rules after deletion")
|
||||
|
||||
err = manager.Reset(nil)
|
||||
err = manager.Close(nil)
|
||||
require.NoError(t, err, "failed to reset")
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ func TestNFtablesCreatePerformance(t *testing.T) {
|
||||
time.Sleep(time.Second * 3)
|
||||
|
||||
defer func() {
|
||||
if err := manager.Reset(nil); err != nil {
|
||||
if err := manager.Close(nil); err != nil {
|
||||
t.Errorf("clear the manager state: %v", err)
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
@@ -274,7 +274,7 @@ func TestNftablesManagerCompatibilityWithIptables(t *testing.T) {
|
||||
require.NoError(t, manager.Init(nil))
|
||||
|
||||
t.Cleanup(func() {
|
||||
err := manager.Reset(nil)
|
||||
err := manager.Close(nil)
|
||||
require.NoError(t, err, "failed to reset manager state")
|
||||
|
||||
// Verify iptables output after reset
|
||||
|
||||
@@ -38,7 +38,7 @@ func TestNftablesManager_AddNatRule(t *testing.T) {
|
||||
// need fw manager to init both acl mgr and router for all chains to be present
|
||||
manager, err := Create(ifaceMock)
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, manager.Reset(nil))
|
||||
require.NoError(t, manager.Close(nil))
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, manager.Init(nil))
|
||||
@@ -127,7 +127,7 @@ func TestNftablesManager_RemoveNatRule(t *testing.T) {
|
||||
t.Run(testCase.Name, func(t *testing.T) {
|
||||
manager, err := Create(ifaceMock)
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, manager.Reset(nil))
|
||||
require.NoError(t, manager.Close(nil))
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, manager.Init(nil))
|
||||
|
||||
@@ -39,7 +39,7 @@ func (s *ShutdownState) Cleanup() error {
|
||||
return fmt.Errorf("create nftables manager: %w", err)
|
||||
}
|
||||
|
||||
if err := nft.Reset(nil); err != nil {
|
||||
if err := nft.Close(nil); err != nil {
|
||||
return fmt.Errorf("reset nftables manager: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
// Reset firewall to the default state
|
||||
func (m *Manager) Reset(stateManager *statemanager.Manager) error {
|
||||
func (m *Manager) Close(stateManager *statemanager.Manager) error {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
|
||||
@@ -48,7 +48,7 @@ func (m *Manager) Reset(stateManager *statemanager.Manager) error {
|
||||
}
|
||||
|
||||
if m.nativeFirewall != nil {
|
||||
return m.nativeFirewall.Reset(stateManager)
|
||||
return m.nativeFirewall.Close(stateManager)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@ const (
|
||||
firewallRuleName = "Netbird"
|
||||
)
|
||||
|
||||
// Reset firewall to the default state
|
||||
func (m *Manager) Reset(*statemanager.Manager) error {
|
||||
// Close closes the firewall manager
|
||||
func (m *Manager) Close(*statemanager.Manager) error {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ func BenchmarkCoreFiltering(b *testing.B) {
|
||||
SetFilterFunc: func(device.PacketFilter) error { return nil },
|
||||
}, false, flowLogger)
|
||||
defer b.Cleanup(func() {
|
||||
require.NoError(b, manager.Reset(nil))
|
||||
require.NoError(b, manager.Close(nil))
|
||||
})
|
||||
|
||||
manager.wgNetwork = &net.IPNet{
|
||||
@@ -216,7 +216,7 @@ func BenchmarkStateScaling(b *testing.B) {
|
||||
SetFilterFunc: func(device.PacketFilter) error { return nil },
|
||||
}, false, flowLogger)
|
||||
b.Cleanup(func() {
|
||||
require.NoError(b, manager.Reset(nil))
|
||||
require.NoError(b, manager.Close(nil))
|
||||
})
|
||||
|
||||
manager.wgNetwork = &net.IPNet{
|
||||
@@ -264,7 +264,7 @@ func BenchmarkEstablishmentOverhead(b *testing.B) {
|
||||
SetFilterFunc: func(device.PacketFilter) error { return nil },
|
||||
}, false, flowLogger)
|
||||
b.Cleanup(func() {
|
||||
require.NoError(b, manager.Reset(nil))
|
||||
require.NoError(b, manager.Close(nil))
|
||||
})
|
||||
|
||||
manager.wgNetwork = &net.IPNet{
|
||||
@@ -463,7 +463,7 @@ func BenchmarkRoutedNetworkReturn(b *testing.B) {
|
||||
SetFilterFunc: func(device.PacketFilter) error { return nil },
|
||||
}, false, flowLogger)
|
||||
b.Cleanup(func() {
|
||||
require.NoError(b, manager.Reset(nil))
|
||||
require.NoError(b, manager.Close(nil))
|
||||
})
|
||||
|
||||
// Setup scenario
|
||||
@@ -590,7 +590,7 @@ func BenchmarkLongLivedConnections(b *testing.B) {
|
||||
SetFilterFunc: func(device.PacketFilter) error { return nil },
|
||||
}, false, flowLogger)
|
||||
defer b.Cleanup(func() {
|
||||
require.NoError(b, manager.Reset(nil))
|
||||
require.NoError(b, manager.Close(nil))
|
||||
})
|
||||
|
||||
manager.SetNetwork(&net.IPNet{
|
||||
@@ -678,7 +678,7 @@ func BenchmarkShortLivedConnections(b *testing.B) {
|
||||
SetFilterFunc: func(device.PacketFilter) error { return nil },
|
||||
}, false, flowLogger)
|
||||
defer b.Cleanup(func() {
|
||||
require.NoError(b, manager.Reset(nil))
|
||||
require.NoError(b, manager.Close(nil))
|
||||
})
|
||||
|
||||
manager.SetNetwork(&net.IPNet{
|
||||
@@ -794,7 +794,7 @@ func BenchmarkParallelLongLivedConnections(b *testing.B) {
|
||||
SetFilterFunc: func(device.PacketFilter) error { return nil },
|
||||
}, false, flowLogger)
|
||||
defer b.Cleanup(func() {
|
||||
require.NoError(b, manager.Reset(nil))
|
||||
require.NoError(b, manager.Close(nil))
|
||||
})
|
||||
|
||||
manager.SetNetwork(&net.IPNet{
|
||||
@@ -879,7 +879,7 @@ func BenchmarkParallelShortLivedConnections(b *testing.B) {
|
||||
SetFilterFunc: func(device.PacketFilter) error { return nil },
|
||||
}, false, flowLogger)
|
||||
defer b.Cleanup(func() {
|
||||
require.NoError(b, manager.Reset(nil))
|
||||
require.NoError(b, manager.Close(nil))
|
||||
})
|
||||
|
||||
manager.SetNetwork(&net.IPNet{
|
||||
|
||||
@@ -39,7 +39,7 @@ func TestPeerACLFiltering(t *testing.T) {
|
||||
require.NotNil(t, manager)
|
||||
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, manager.Reset(nil))
|
||||
require.NoError(t, manager.Close(nil))
|
||||
})
|
||||
|
||||
manager.wgNetwork = wgNet
|
||||
@@ -310,7 +310,7 @@ func setupRoutedManager(tb testing.TB, network string) *Manager {
|
||||
require.False(tb, manager.nativeRouter)
|
||||
|
||||
tb.Cleanup(func() {
|
||||
require.NoError(tb, manager.Reset(nil))
|
||||
require.NoError(tb, manager.Close(nil))
|
||||
})
|
||||
|
||||
return manager
|
||||
|
||||
@@ -255,7 +255,7 @@ func TestManagerReset(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
err = m.Reset(nil)
|
||||
err = m.Close(nil)
|
||||
if err != nil {
|
||||
t.Errorf("failed to reset Manager: %v", err)
|
||||
return
|
||||
@@ -333,7 +333,7 @@ func TestNotMatchByIP(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = m.Reset(nil); err != nil {
|
||||
if err = m.Close(nil); err != nil {
|
||||
t.Errorf("failed to reset Manager: %v", err)
|
||||
return
|
||||
}
|
||||
@@ -352,7 +352,7 @@ func TestRemovePacketHook(t *testing.T) {
|
||||
t.Fatalf("Failed to create Manager: %s", err)
|
||||
}
|
||||
defer func() {
|
||||
require.NoError(t, manager.Reset(nil))
|
||||
require.NoError(t, manager.Close(nil))
|
||||
}()
|
||||
|
||||
// Add a UDP packet hook
|
||||
@@ -403,7 +403,7 @@ func TestProcessOutgoingHooks(t *testing.T) {
|
||||
manager.udpTracker.Close()
|
||||
manager.udpTracker = conntrack.NewUDPTracker(100*time.Millisecond, logger, flowLogger)
|
||||
defer func() {
|
||||
require.NoError(t, manager.Reset(nil))
|
||||
require.NoError(t, manager.Close(nil))
|
||||
}()
|
||||
|
||||
manager.decoders = sync.Pool{
|
||||
@@ -484,7 +484,7 @@ func TestUSPFilterCreatePerformance(t *testing.T) {
|
||||
time.Sleep(time.Second)
|
||||
|
||||
defer func() {
|
||||
if err := manager.Reset(nil); err != nil {
|
||||
if err := manager.Close(nil); err != nil {
|
||||
t.Errorf("clear the manager state: %v", err)
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
@@ -530,7 +530,7 @@ func TestStatefulFirewall_UDPTracking(t *testing.T) {
|
||||
},
|
||||
}
|
||||
defer func() {
|
||||
require.NoError(t, manager.Reset(nil))
|
||||
require.NoError(t, manager.Close(nil))
|
||||
}()
|
||||
|
||||
// Set up packet parameters
|
||||
|
||||
@@ -55,7 +55,7 @@ func (t *NetStackTun) Create() (tun.Device, *netstack.Net, error) {
|
||||
|
||||
skipProxy, err := strconv.ParseBool(os.Getenv(EnvSkipProxy))
|
||||
if err != nil {
|
||||
log.Errorf("failed to parse NB_ETSTACK_SKIP_PROXY: %s", err)
|
||||
log.Errorf("failed to parse %s: %s", EnvSkipProxy, err)
|
||||
}
|
||||
if skipProxy {
|
||||
return nsTunDev, tunNet, nil
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
!define DESCRIPTION "A WireGuard®-based mesh network that connects your devices into a single private network"
|
||||
!define INSTALLER_NAME "netbird-installer.exe"
|
||||
!define MAIN_APP_EXE "Netbird"
|
||||
!define ICON "ui\\netbird.ico"
|
||||
!define BANNER "ui\\banner.bmp"
|
||||
!define ICON "ui\\assets\\netbird.ico"
|
||||
!define BANNER "ui\\build\\banner.bmp"
|
||||
!define LICENSE_DATA "..\\LICENSE"
|
||||
|
||||
!define INSTALL_DIR "$PROGRAMFILES64\${APP_NAME}"
|
||||
|
||||
@@ -62,7 +62,7 @@ func TestDefaultManager(t *testing.T) {
|
||||
return
|
||||
}
|
||||
defer func(fw manager.Manager) {
|
||||
_ = fw.Reset(nil)
|
||||
_ = fw.Close(nil)
|
||||
}(fw)
|
||||
acl := NewDefaultManager(fw)
|
||||
|
||||
@@ -356,7 +356,7 @@ func TestDefaultManagerEnableSSHRules(t *testing.T) {
|
||||
return
|
||||
}
|
||||
defer func(fw manager.Manager) {
|
||||
_ = fw.Reset(nil)
|
||||
_ = fw.Close(nil)
|
||||
}(fw)
|
||||
acl := NewDefaultManager(fw)
|
||||
|
||||
|
||||
@@ -1018,7 +1018,7 @@ func TestHandlerChain_DomainPriorities(t *testing.T) {
|
||||
mh.AssertExpectations(t)
|
||||
}
|
||||
|
||||
// Reset mocks
|
||||
// Close mocks
|
||||
if mh, ok := tc.expectedHandler.(*MockHandler); ok {
|
||||
mh.ExpectedCalls = nil
|
||||
mh.Calls = nil
|
||||
|
||||
@@ -1428,7 +1428,7 @@ func (e *Engine) close() {
|
||||
}
|
||||
|
||||
if e.firewall != nil {
|
||||
err := e.firewall.Reset(e.stateManager)
|
||||
err := e.firewall.Close(e.stateManager)
|
||||
if err != nil {
|
||||
log.Warnf("failed to reset firewall: %s", err)
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
</InstallExecuteSequence>
|
||||
|
||||
<!-- Icons -->
|
||||
<Icon Id="NetbirdIcon" SourceFile=".\client\ui\netbird.ico" />
|
||||
<Icon Id="NetbirdIcon" SourceFile=".\client\ui\assets\netbird.ico" />
|
||||
<Property Id="ARPPRODUCTICON" Value="NetbirdIcon" />
|
||||
|
||||
</Package>
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
#define STRINGIZE(x) #x
|
||||
#define EXPAND(x) STRINGIZE(x)
|
||||
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST manifest.xml
|
||||
7 ICON ui/netbird.ico
|
||||
7 ICON ui/assets/netbird.ico
|
||||
wintun.dll RCDATA wintun.dll
|
||||
|
||||
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
@@ -35,7 +35,9 @@ import (
|
||||
"github.com/netbirdio/netbird/client/proto"
|
||||
"github.com/netbirdio/netbird/client/ui/desktop"
|
||||
"github.com/netbirdio/netbird/client/ui/event"
|
||||
"github.com/netbirdio/netbird/client/ui/process"
|
||||
"github.com/netbirdio/netbird/util"
|
||||
|
||||
"github.com/netbirdio/netbird/version"
|
||||
)
|
||||
|
||||
@@ -44,94 +46,125 @@ const (
|
||||
failFastTimeout = time.Second
|
||||
)
|
||||
|
||||
const (
|
||||
censoredPreSharedKey = "**********"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var daemonAddr string
|
||||
|
||||
defaultDaemonAddr := "unix:///var/run/netbird.sock"
|
||||
if runtime.GOOS == "windows" {
|
||||
defaultDaemonAddr = "tcp://127.0.0.1:41731"
|
||||
}
|
||||
|
||||
flag.StringVar(
|
||||
&daemonAddr, "daemon-addr",
|
||||
defaultDaemonAddr,
|
||||
"Daemon service address to serve CLI requests [unix|tcp]://[path|host:port]")
|
||||
|
||||
var showSettings bool
|
||||
flag.BoolVar(&showSettings, "settings", false, "run settings windows")
|
||||
var showRoutes bool
|
||||
flag.BoolVar(&showRoutes, "networks", false, "run networks windows")
|
||||
var errorMSG string
|
||||
flag.StringVar(&errorMSG, "error-msg", "", "displays a error message window")
|
||||
|
||||
tmpDir := "/tmp"
|
||||
if runtime.GOOS == "windows" {
|
||||
tmpDir = os.TempDir()
|
||||
}
|
||||
|
||||
var saveLogsInFile bool
|
||||
flag.BoolVar(&saveLogsInFile, "use-log-file", false, fmt.Sprintf("save logs in a file: %s/netbird-ui-PID.log", tmpDir))
|
||||
|
||||
flag.Parse()
|
||||
daemonAddr, showSettings, showNetworks, errorMsg, saveLogsInFile := parseFlags()
|
||||
|
||||
// Initialize file logging if needed.
|
||||
if saveLogsInFile {
|
||||
logFile := path.Join(tmpDir, fmt.Sprintf("netbird-ui-%d.log", os.Getpid()))
|
||||
err := util.InitLog("trace", logFile)
|
||||
if err != nil {
|
||||
if err := initLogFile(); err != nil {
|
||||
log.Errorf("error while initializing log: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Create the Fyne application.
|
||||
a := app.NewWithID("NetBird")
|
||||
a.SetIcon(fyne.NewStaticResource("netbird", iconDisconnected))
|
||||
|
||||
if errorMSG != "" {
|
||||
showErrorMSG(errorMSG)
|
||||
// Show error message window if needed.
|
||||
if errorMsg != "" {
|
||||
showErrorMessage(errorMsg)
|
||||
return
|
||||
}
|
||||
|
||||
client := newServiceClient(daemonAddr, a, showSettings, showRoutes)
|
||||
// Create the service client (this also builds the settings or networks UI if requested).
|
||||
client := newServiceClient(daemonAddr, a, showSettings, showNetworks)
|
||||
|
||||
// Watch for theme/settings changes to update the icon.
|
||||
go watchSettingsChanges(a, client)
|
||||
|
||||
// Run in window mode if any UI flag was set.
|
||||
if showSettings || showNetworks {
|
||||
a.Run()
|
||||
return
|
||||
}
|
||||
|
||||
// Check for another running process.
|
||||
running, err := process.IsAnotherProcessRunning()
|
||||
if err != nil {
|
||||
log.Errorf("error while checking process: %v", err)
|
||||
return
|
||||
}
|
||||
if running {
|
||||
log.Warn("another process is running")
|
||||
return
|
||||
}
|
||||
|
||||
client.setDefaultFonts()
|
||||
systray.Run(client.onTrayReady, client.onTrayExit)
|
||||
}
|
||||
|
||||
// parseFlags reads and returns all needed command-line flags.
|
||||
func parseFlags() (daemonAddr string, showSettings, showNetworks bool, errorMsg string, saveLogsInFile bool) {
|
||||
defaultDaemonAddr := "unix:///var/run/netbird.sock"
|
||||
if runtime.GOOS == "windows" {
|
||||
defaultDaemonAddr = "tcp://127.0.0.1:41731"
|
||||
}
|
||||
flag.StringVar(&daemonAddr, "daemon-addr", defaultDaemonAddr, "Daemon service address to serve CLI requests [unix|tcp]://[path|host:port]")
|
||||
flag.BoolVar(&showSettings, "settings", false, "run settings window")
|
||||
flag.BoolVar(&showNetworks, "networks", false, "run networks window")
|
||||
flag.StringVar(&errorMsg, "error-msg", "", "displays an error message window")
|
||||
|
||||
tmpDir := "/tmp"
|
||||
if runtime.GOOS == "windows" {
|
||||
tmpDir = os.TempDir()
|
||||
}
|
||||
flag.BoolVar(&saveLogsInFile, "use-log-file", false, fmt.Sprintf("save logs in a file: %s/netbird-ui-PID.log", tmpDir))
|
||||
flag.Parse()
|
||||
return
|
||||
}
|
||||
|
||||
// initLogFile initializes logging into a file.
|
||||
func initLogFile() error {
|
||||
tmpDir := "/tmp"
|
||||
if runtime.GOOS == "windows" {
|
||||
tmpDir = os.TempDir()
|
||||
}
|
||||
logFile := path.Join(tmpDir, fmt.Sprintf("netbird-ui-%d.log", os.Getpid()))
|
||||
return util.InitLog("trace", logFile)
|
||||
}
|
||||
|
||||
// watchSettingsChanges listens for Fyne theme/settings changes and updates the client icon.
|
||||
func watchSettingsChanges(a fyne.App, client *serviceClient) {
|
||||
settingsChangeChan := make(chan fyne.Settings)
|
||||
a.Settings().AddChangeListener(settingsChangeChan)
|
||||
go func() {
|
||||
for range settingsChangeChan {
|
||||
client.updateIcon()
|
||||
}
|
||||
}()
|
||||
|
||||
if showSettings || showRoutes {
|
||||
a.Run()
|
||||
} else {
|
||||
running, err := isAnotherProcessRunning()
|
||||
if err != nil {
|
||||
log.Errorf("error while checking process: %v", err)
|
||||
}
|
||||
if running {
|
||||
log.Warn("another process is running")
|
||||
return
|
||||
}
|
||||
client.setDefaultFonts()
|
||||
systray.Run(client.onTrayReady, client.onTrayExit)
|
||||
for range settingsChangeChan {
|
||||
client.updateIcon()
|
||||
}
|
||||
}
|
||||
|
||||
//go:embed netbird-systemtray-connected-macos.png
|
||||
// showErrorMessage displays an error message in a simple window.
|
||||
func showErrorMessage(msg string) {
|
||||
a := app.New()
|
||||
w := a.NewWindow("NetBird Error")
|
||||
label := widget.NewLabel(msg)
|
||||
label.Wrapping = fyne.TextWrapWord
|
||||
w.SetContent(label)
|
||||
w.Resize(fyne.NewSize(400, 100))
|
||||
w.Show()
|
||||
a.Run()
|
||||
}
|
||||
|
||||
//go:embed assets/netbird-systemtray-connected-macos.png
|
||||
var iconConnectedMacOS []byte
|
||||
|
||||
//go:embed netbird-systemtray-disconnected-macos.png
|
||||
//go:embed assets/netbird-systemtray-disconnected-macos.png
|
||||
var iconDisconnectedMacOS []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-disconnected-macos.png
|
||||
//go:embed assets/netbird-systemtray-update-disconnected-macos.png
|
||||
var iconUpdateDisconnectedMacOS []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-connected-macos.png
|
||||
//go:embed assets/netbird-systemtray-update-connected-macos.png
|
||||
var iconUpdateConnectedMacOS []byte
|
||||
|
||||
//go:embed netbird-systemtray-connecting-macos.png
|
||||
//go:embed assets/netbird-systemtray-connecting-macos.png
|
||||
var iconConnectingMacOS []byte
|
||||
|
||||
//go:embed netbird-systemtray-error-macos.png
|
||||
//go:embed assets/netbird-systemtray-error-macos.png
|
||||
var iconErrorMacOS []byte
|
||||
|
||||
type serviceClient struct {
|
||||
@@ -154,6 +187,7 @@ type serviceClient struct {
|
||||
mAdminPanel *systray.MenuItem
|
||||
mSettings *systray.MenuItem
|
||||
mAbout *systray.MenuItem
|
||||
mGitHub *systray.MenuItem
|
||||
mVersionUI *systray.MenuItem
|
||||
mVersionDaemon *systray.MenuItem
|
||||
mUpdate *systray.MenuItem
|
||||
@@ -300,18 +334,6 @@ func (s *serviceClient) showSettingsUI() {
|
||||
s.wSettings.Show()
|
||||
}
|
||||
|
||||
// showErrorMSG opens a fyne app window to display the supplied message
|
||||
func showErrorMSG(msg string) {
|
||||
app := app.New()
|
||||
w := app.NewWindow("NetBird Error")
|
||||
content := widget.NewLabel(msg)
|
||||
content.Wrapping = fyne.TextWrapWord
|
||||
w.SetContent(content)
|
||||
w.Resize(fyne.NewSize(400, 100))
|
||||
w.Show()
|
||||
app.Run()
|
||||
}
|
||||
|
||||
// getSettingsForm to embed it into settings window.
|
||||
func (s *serviceClient) getSettingsForm() *widget.Form {
|
||||
return &widget.Form{
|
||||
@@ -327,7 +349,7 @@ func (s *serviceClient) getSettingsForm() *widget.Form {
|
||||
},
|
||||
SubmitText: "Save",
|
||||
OnSubmit: func() {
|
||||
if s.iPreSharedKey.Text != "" && s.iPreSharedKey.Text != "**********" {
|
||||
if s.iPreSharedKey.Text != "" && s.iPreSharedKey.Text != censoredPreSharedKey {
|
||||
// validate preSharedKey if it added
|
||||
if _, err := wgtypes.ParseKey(s.iPreSharedKey.Text); err != nil {
|
||||
dialog.ShowError(fmt.Errorf("Invalid Pre-shared Key Value"), s.wSettings)
|
||||
@@ -365,7 +387,7 @@ func (s *serviceClient) getSettingsForm() *widget.Form {
|
||||
WireguardPort: &port,
|
||||
}
|
||||
|
||||
if s.iPreSharedKey.Text != "**********" {
|
||||
if s.iPreSharedKey.Text != censoredPreSharedKey {
|
||||
loginRequest.OptionalPreSharedKey = &s.iPreSharedKey.Text
|
||||
}
|
||||
|
||||
@@ -587,26 +609,29 @@ func (s *serviceClient) onTrayReady() {
|
||||
s.mAdminPanel = systray.AddMenuItem("Admin Panel", "Netbird Admin Panel")
|
||||
systray.AddSeparator()
|
||||
|
||||
s.mSettings = systray.AddMenuItem("Settings", "Settings of the application")
|
||||
s.mAllowSSH = s.mSettings.AddSubMenuItemCheckbox("Allow SSH", "Allow SSH connections", false)
|
||||
s.mAutoConnect = s.mSettings.AddSubMenuItemCheckbox("Connect on Startup", "Connect automatically when the service starts", false)
|
||||
s.mEnableRosenpass = s.mSettings.AddSubMenuItemCheckbox("Enable Quantum-Resistance", "Enable post-quantum security via Rosenpass", false)
|
||||
s.mNotifications = s.mSettings.AddSubMenuItemCheckbox("Notifications", "Enable notifications", false)
|
||||
s.mAdvancedSettings = s.mSettings.AddSubMenuItem("Advanced Settings", "Advanced settings of the application")
|
||||
s.mCreateDebugBundle = s.mSettings.AddSubMenuItem("Create Debug Bundle", "Create and open debug information bundle")
|
||||
s.mSettings = systray.AddMenuItem("Settings", settingsMenuDescr)
|
||||
s.mAllowSSH = s.mSettings.AddSubMenuItemCheckbox("Allow SSH", allowSSHMenuDescr, false)
|
||||
s.mAutoConnect = s.mSettings.AddSubMenuItemCheckbox("Connect on Startup", autoConnectMenuDescr, false)
|
||||
s.mEnableRosenpass = s.mSettings.AddSubMenuItemCheckbox("Enable Quantum-Resistance", quantumResistanceMenuDescr, false)
|
||||
s.mNotifications = s.mSettings.AddSubMenuItemCheckbox("Notifications", notificationsMenuDescr, false)
|
||||
s.mAdvancedSettings = s.mSettings.AddSubMenuItem("Advanced Settings", advancedSettingsMenuDescr)
|
||||
s.mCreateDebugBundle = s.mSettings.AddSubMenuItem("Create Debug Bundle", debugBundleMenuDescr)
|
||||
s.loadSettings()
|
||||
|
||||
s.exitNodeMu.Lock()
|
||||
s.mExitNode = systray.AddMenuItem("Exit Node", "Select exit node for routing traffic")
|
||||
s.mExitNode = systray.AddMenuItem("Exit Node", exitNodeMenuDescr)
|
||||
s.mExitNode.Disable()
|
||||
s.exitNodeMu.Unlock()
|
||||
|
||||
s.mNetworks = systray.AddMenuItem("Networks", "Open the networks management window")
|
||||
s.mNetworks = systray.AddMenuItem("Networks", networksMenuDescr)
|
||||
s.mNetworks.Disable()
|
||||
systray.AddSeparator()
|
||||
|
||||
s.mAbout = systray.AddMenuItem("About", "About")
|
||||
s.mAbout.SetIcon(s.icAbout)
|
||||
|
||||
s.mGitHub = s.mAbout.AddSubMenuItem("GitHub", "GitHub")
|
||||
|
||||
versionString := normalizedVersion(version.NetbirdVersion())
|
||||
s.mVersionUI = s.mAbout.AddSubMenuItem(fmt.Sprintf("GUI: %s", versionString), fmt.Sprintf("GUI Version: %s", versionString))
|
||||
s.mVersionUI.Disable()
|
||||
@@ -615,11 +640,11 @@ func (s *serviceClient) onTrayReady() {
|
||||
s.mVersionDaemon.Disable()
|
||||
s.mVersionDaemon.Hide()
|
||||
|
||||
s.mUpdate = s.mAbout.AddSubMenuItem("Download latest version", "Download latest version")
|
||||
s.mUpdate = s.mAbout.AddSubMenuItem("Download latest version", latestVersionMenuDescr)
|
||||
s.mUpdate.Hide()
|
||||
|
||||
systray.AddSeparator()
|
||||
s.mQuit = systray.AddMenuItem("Quit", "Quit the client app")
|
||||
s.mQuit = systray.AddMenuItem("Quit", quitMenuDescr)
|
||||
|
||||
// update exit node menu in case service is already connected
|
||||
go s.updateExitNodes()
|
||||
@@ -717,6 +742,11 @@ func (s *serviceClient) onTrayReady() {
|
||||
case <-s.mQuit.ClickedCh:
|
||||
systray.Quit()
|
||||
return
|
||||
case <-s.mGitHub.ClickedCh:
|
||||
err := openURL("https://github.com/netbirdio/netbird")
|
||||
if err != nil {
|
||||
log.Errorf("%s", err)
|
||||
}
|
||||
case <-s.mUpdate.ClickedCh:
|
||||
err := openURL(version.DownloadUrl())
|
||||
if err != nil {
|
||||
|
||||
15
client/ui/const.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package main
|
||||
|
||||
const (
|
||||
settingsMenuDescr = "Settings of the application"
|
||||
allowSSHMenuDescr = "Allow SSH connections"
|
||||
autoConnectMenuDescr = "Connect automatically when the service starts"
|
||||
quantumResistanceMenuDescr = "Enable post-quantum security via Rosenpass"
|
||||
notificationsMenuDescr = "Enable notifications"
|
||||
advancedSettingsMenuDescr = "Advanced settings of the application"
|
||||
debugBundleMenuDescr = "Create and open debug information bundle"
|
||||
exitNodeMenuDescr = "Select exit node for routing traffic"
|
||||
networksMenuDescr = "Open the networks management window"
|
||||
latestVersionMenuDescr = "Download latest version"
|
||||
quitMenuDescr = "Quit the client app"
|
||||
)
|
||||
@@ -6,38 +6,38 @@ import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed netbird.png
|
||||
//go:embed assets/netbird.png
|
||||
var iconAbout []byte
|
||||
|
||||
//go:embed netbird-systemtray-connected.png
|
||||
//go:embed assets/netbird-systemtray-connected.png
|
||||
var iconConnected []byte
|
||||
|
||||
//go:embed netbird-systemtray-connected-dark.png
|
||||
//go:embed assets/netbird-systemtray-connected-dark.png
|
||||
var iconConnectedDark []byte
|
||||
|
||||
//go:embed netbird-systemtray-disconnected.png
|
||||
//go:embed assets/netbird-systemtray-disconnected.png
|
||||
var iconDisconnected []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-disconnected.png
|
||||
//go:embed assets/netbird-systemtray-update-disconnected.png
|
||||
var iconUpdateDisconnected []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-disconnected-dark.png
|
||||
//go:embed assets/netbird-systemtray-update-disconnected-dark.png
|
||||
var iconUpdateDisconnectedDark []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-connected.png
|
||||
//go:embed assets/netbird-systemtray-update-connected.png
|
||||
var iconUpdateConnected []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-connected-dark.png
|
||||
//go:embed assets/netbird-systemtray-update-connected-dark.png
|
||||
var iconUpdateConnectedDark []byte
|
||||
|
||||
//go:embed netbird-systemtray-connecting.png
|
||||
//go:embed assets/netbird-systemtray-connecting.png
|
||||
var iconConnecting []byte
|
||||
|
||||
//go:embed netbird-systemtray-connecting-dark.png
|
||||
//go:embed assets/netbird-systemtray-connecting-dark.png
|
||||
var iconConnectingDark []byte
|
||||
|
||||
//go:embed netbird-systemtray-error.png
|
||||
//go:embed assets/netbird-systemtray-error.png
|
||||
var iconError []byte
|
||||
|
||||
//go:embed netbird-systemtray-error-dark.png
|
||||
//go:embed assets/netbird-systemtray-error-dark.png
|
||||
var iconErrorDark []byte
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed netbird.ico
|
||||
//go:embed assets/netbird.ico
|
||||
var iconAbout []byte
|
||||
|
||||
//go:embed netbird-systemtray-connected.ico
|
||||
//go:embed assets/netbird-systemtray-connected.ico
|
||||
var iconConnected []byte
|
||||
|
||||
//go:embed netbird-systemtray-connected-dark.ico
|
||||
//go:embed assets/netbird-systemtray-connected-dark.ico
|
||||
var iconConnectedDark []byte
|
||||
|
||||
//go:embed netbird-systemtray-disconnected.ico
|
||||
//go:embed assets/netbird-systemtray-disconnected.ico
|
||||
var iconDisconnected []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-disconnected.ico
|
||||
//go:embed assets/netbird-systemtray-update-disconnected.ico
|
||||
var iconUpdateDisconnected []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-disconnected-dark.ico
|
||||
//go:embed assets/netbird-systemtray-update-disconnected-dark.ico
|
||||
var iconUpdateDisconnectedDark []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-connected.ico
|
||||
//go:embed assets/netbird-systemtray-update-connected.ico
|
||||
var iconUpdateConnected []byte
|
||||
|
||||
//go:embed netbird-systemtray-update-connected-dark.ico
|
||||
//go:embed assets/netbird-systemtray-update-connected-dark.ico
|
||||
var iconUpdateConnectedDark []byte
|
||||
|
||||
//go:embed netbird-systemtray-connecting.ico
|
||||
//go:embed assets/netbird-systemtray-connecting.ico
|
||||
var iconConnecting []byte
|
||||
|
||||
//go:embed netbird-systemtray-connecting-dark.ico
|
||||
//go:embed assets/netbird-systemtray-connecting-dark.ico
|
||||
var iconConnectingDark []byte
|
||||
|
||||
//go:embed netbird-systemtray-error.ico
|
||||
//go:embed assets/netbird-systemtray-error.ico
|
||||
var iconError []byte
|
||||
|
||||
//go:embed netbird-systemtray-error-dark.ico
|
||||
//go:embed assets/netbird-systemtray-error-dark.ico
|
||||
var iconErrorDark []byte
|
||||
|
||||
@@ -363,7 +363,7 @@ func (s *serviceClient) recreateExitNodeMenu(exitNodes []*proto.Network) {
|
||||
|
||||
if runtime.GOOS == "linux" || runtime.GOOS == "freebsd" {
|
||||
s.mExitNode.Remove()
|
||||
s.mExitNode = systray.AddMenuItem("Exit Node", "Select exit node for routing traffic")
|
||||
s.mExitNode = systray.AddMenuItem("Exit Node", exitNodeMenuDescr)
|
||||
}
|
||||
|
||||
for _, node := range exitNodes {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package process
|
||||
|
||||
import (
|
||||
"os"
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"github.com/shirou/gopsutil/v3/process"
|
||||
)
|
||||
|
||||
func isAnotherProcessRunning() (bool, error) {
|
||||
func IsAnotherProcessRunning() (bool, error) {
|
||||
processes, err := process.Processes()
|
||||
if err != nil {
|
||||
return false, err
|
||||
@@ -1,6 +1,6 @@
|
||||
//go:build !windows
|
||||
|
||||
package main
|
||||
package process
|
||||
|
||||
import (
|
||||
"os"
|
||||
@@ -1,4 +1,4 @@
|
||||
package main
|
||||
package process
|
||||
|
||||
import (
|
||||
"os/user"
|
||||
5
go.mod
@@ -60,7 +60,8 @@ require (
|
||||
github.com/miekg/dns v1.1.59
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2
|
||||
github.com/nadoo/ipset v0.5.0
|
||||
github.com/netbirdio/management-integrations/integrations v0.0.0-20250226165736-0ac3dc443266
|
||||
github.com/netbirdio/management-integrations/core v0.0.0-00010101000000-000000000000
|
||||
github.com/netbirdio/management-integrations/integrations v0.0.0-20250220173202-e599d83524fc
|
||||
github.com/netbirdio/signal-dispatcher/dispatcher v0.0.0-20241010133937-e0df50df217d
|
||||
github.com/okta/okta-sdk-golang/v2 v2.18.0
|
||||
github.com/oschwald/maxminddb-golang v1.12.0
|
||||
@@ -254,3 +255,5 @@ replace github.com/cloudflare/circl => github.com/cunicu/circl v0.0.0-2023080111
|
||||
replace github.com/pion/ice/v3 => github.com/netbirdio/ice/v3 v3.0.0-20240315174635-e72a50fcb64e
|
||||
|
||||
replace github.com/libp2p/go-netroute => github.com/netbirdio/go-netroute v0.0.0-20240611143515-f59b0e1d3944
|
||||
|
||||
replace github.com/netbirdio/management-integrations/core => ../../management-integrations/core
|
||||
|
||||
@@ -34,7 +34,6 @@ var tokenPathRegexp = regexp.MustCompile(`^.*/api/users/.*/tokens.*$`)
|
||||
// Handler method of the middleware which forbids all modify requests for non admin users
|
||||
func (a *AccessControl) Handler(h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if bypass.ShouldBypass(r.URL.Path, h, w, r) {
|
||||
return
|
||||
}
|
||||
@@ -60,18 +59,16 @@ func (a *AccessControl) Handler(h http.Handler) http.Handler {
|
||||
if !user.HasAdminPower() {
|
||||
switch r.Method {
|
||||
case http.MethodDelete, http.MethodPost, http.MethodPatch, http.MethodPut:
|
||||
|
||||
if tokenPathRegexp.MatchString(r.URL.Path) {
|
||||
log.WithContext(r.Context()).Debugf("valid Path")
|
||||
h.ServeHTTP(w, r)
|
||||
if !tokenPathRegexp.MatchString(r.URL.Path) {
|
||||
util.WriteError(r.Context(), status.Errorf(status.PermissionDenied, "only users with admin power can perform this operation"), w)
|
||||
return
|
||||
}
|
||||
|
||||
util.WriteError(r.Context(), status.Errorf(status.PermissionDenied, "only users with admin power can perform this operation"), w)
|
||||
return
|
||||
log.WithContext(r.Context()).Debugf("valid Path")
|
||||
}
|
||||
}
|
||||
|
||||
// @todo get account settings and set it and user to context
|
||||
h.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@ import (
|
||||
|
||||
"github.com/rs/xid"
|
||||
|
||||
"github.com/netbirdio/management-integrations/core"
|
||||
"github.com/netbirdio/netbird/management/server/account"
|
||||
"github.com/netbirdio/netbird/management/server/activity"
|
||||
"github.com/netbirdio/netbird/management/server/networks/resources"
|
||||
"github.com/netbirdio/netbird/management/server/networks/routers"
|
||||
"github.com/netbirdio/netbird/management/server/networks/types"
|
||||
"github.com/netbirdio/netbird/management/server/permissions"
|
||||
"github.com/netbirdio/netbird/management/server/status"
|
||||
"github.com/netbirdio/netbird/management/server/store"
|
||||
)
|
||||
|
||||
@@ -25,6 +25,7 @@ type Manager interface {
|
||||
}
|
||||
|
||||
type managerImpl struct {
|
||||
core.BaseManager
|
||||
store store.Store
|
||||
accountManager account.AccountManager
|
||||
permissionsManager permissions.Manager
|
||||
@@ -37,33 +38,28 @@ type mockManager struct {
|
||||
|
||||
func NewManager(store store.Store, permissionsManager permissions.Manager, resourceManager resources.Manager, routersManager routers.Manager, accountManager account.AccountManager) Manager {
|
||||
return &managerImpl{
|
||||
store: store,
|
||||
permissionsManager: permissionsManager,
|
||||
resourcesManager: resourceManager,
|
||||
routersManager: routersManager,
|
||||
accountManager: accountManager,
|
||||
BaseManager: core.NewBaseManager(core.Networks),
|
||||
store: store,
|
||||
// permissionsManager: permissionsManager,
|
||||
resourcesManager: resourceManager,
|
||||
routersManager: routersManager,
|
||||
accountManager: accountManager,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *managerImpl) GetAllNetworks(ctx context.Context, accountID, userID string) ([]*types.Network, error) {
|
||||
ok, err := m.permissionsManager.ValidateUserPermissions(ctx, accountID, userID, permissions.Networks, permissions.Read)
|
||||
err := m.ValidatePermissions(ctx, core.Read)
|
||||
if err != nil {
|
||||
return nil, status.NewPermissionValidationError(err)
|
||||
}
|
||||
if !ok {
|
||||
return nil, status.NewPermissionDeniedError()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return m.store.GetAccountNetworks(ctx, store.LockingStrengthShare, accountID)
|
||||
}
|
||||
|
||||
func (m *managerImpl) CreateNetwork(ctx context.Context, userID string, network *types.Network) (*types.Network, error) {
|
||||
ok, err := m.permissionsManager.ValidateUserPermissions(ctx, network.AccountID, userID, permissions.Networks, permissions.Write)
|
||||
err := m.ValidatePermissions(ctx, core.Write)
|
||||
if err != nil {
|
||||
return nil, status.NewPermissionValidationError(err)
|
||||
}
|
||||
if !ok {
|
||||
return nil, status.NewPermissionDeniedError()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
network.ID = xid.New().String()
|
||||
@@ -82,24 +78,18 @@ func (m *managerImpl) CreateNetwork(ctx context.Context, userID string, network
|
||||
}
|
||||
|
||||
func (m *managerImpl) GetNetwork(ctx context.Context, accountID, userID, networkID string) (*types.Network, error) {
|
||||
ok, err := m.permissionsManager.ValidateUserPermissions(ctx, accountID, userID, permissions.Networks, permissions.Read)
|
||||
err := m.ValidatePermissions(ctx, core.Read)
|
||||
if err != nil {
|
||||
return nil, status.NewPermissionValidationError(err)
|
||||
}
|
||||
if !ok {
|
||||
return nil, status.NewPermissionDeniedError()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return m.store.GetNetworkByID(ctx, store.LockingStrengthShare, accountID, networkID)
|
||||
}
|
||||
|
||||
func (m *managerImpl) UpdateNetwork(ctx context.Context, userID string, network *types.Network) (*types.Network, error) {
|
||||
ok, err := m.permissionsManager.ValidateUserPermissions(ctx, network.AccountID, userID, permissions.Networks, permissions.Write)
|
||||
err := m.ValidatePermissions(ctx, core.Write)
|
||||
if err != nil {
|
||||
return nil, status.NewPermissionValidationError(err)
|
||||
}
|
||||
if !ok {
|
||||
return nil, status.NewPermissionDeniedError()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
unlock := m.store.AcquireWriteLockByUID(ctx, network.AccountID)
|
||||
@@ -116,12 +106,9 @@ func (m *managerImpl) UpdateNetwork(ctx context.Context, userID string, network
|
||||
}
|
||||
|
||||
func (m *managerImpl) DeleteNetwork(ctx context.Context, accountID, userID, networkID string) error {
|
||||
ok, err := m.permissionsManager.ValidateUserPermissions(ctx, accountID, userID, permissions.Networks, permissions.Write)
|
||||
err := m.ValidatePermissions(ctx, core.Write)
|
||||
if err != nil {
|
||||
return status.NewPermissionValidationError(err)
|
||||
}
|
||||
if !ok {
|
||||
return status.NewPermissionDeniedError()
|
||||
return err
|
||||
}
|
||||
|
||||
network, err := m.store.GetNetworkByID(ctx, store.LockingStrengthUpdate, accountID, networkID)
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
nbcontext "github.com/netbirdio/netbird/management/server/context"
|
||||
"github.com/netbirdio/netbird/management/server/groups"
|
||||
"github.com/netbirdio/netbird/management/server/mock_server"
|
||||
"github.com/netbirdio/netbird/management/server/networks/resources"
|
||||
@@ -25,6 +26,7 @@ func Test_GetAllNetworksReturnsNetworks(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(cleanUp)
|
||||
|
||||
am := mock_server.MockAccountManager{}
|
||||
permissionsManager := permissions.NewManagerMock()
|
||||
groupsManager := groups.NewManagerMock()
|
||||
@@ -32,6 +34,7 @@ func Test_GetAllNetworksReturnsNetworks(t *testing.T) {
|
||||
resourcesManager := resources.NewManager(s, permissionsManager, groupsManager, &am)
|
||||
manager := NewManager(s, permissionsManager, resourcesManager, routerManager, &am)
|
||||
|
||||
ctx = nbcontext.SetUserAuthInContext(ctx, nbcontext.UserAuth{AccountId: accountID, UserId: userID})
|
||||
networks, err := manager.GetAllNetworks(ctx, accountID, userID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, networks, 1)
|
||||
|
||||
@@ -371,6 +371,9 @@ func (am *DefaultAccountManager) DeletePeer(ctx context.Context, accountID, peer
|
||||
eventsToStore, err = deletePeers(ctx, am, transaction, accountID, userID, []*nbpeer.Peer{peer})
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, storeEvent := range eventsToStore {
|
||||
storeEvent()
|
||||
|
||||