mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-25 11:46:40 +00:00
Compare commits
12 Commits
feature/bu
...
v0.44.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99f8dc7748 | ||
|
|
f1de8e6eb0 | ||
|
|
b2a10780af | ||
|
|
43ae79d848 | ||
|
|
e520b64c6d | ||
|
|
92c91bbdd8 | ||
|
|
adf494e1ac | ||
|
|
2158461121 | ||
|
|
0cd4b601c3 | ||
|
|
ee1cec47b3 | ||
|
|
efb0edfc4c | ||
|
|
20f59ddecb |
@@ -179,6 +179,7 @@ jobs:
|
|||||||
grep -A 7 Relay management.json | grep "rel://$CI_NETBIRD_DOMAIN:33445"
|
grep -A 7 Relay management.json | grep "rel://$CI_NETBIRD_DOMAIN:33445"
|
||||||
grep -A 7 Relay management.json | egrep '"Secret": ".+"'
|
grep -A 7 Relay management.json | egrep '"Secret": ".+"'
|
||||||
grep DisablePromptLogin management.json | grep 'true'
|
grep DisablePromptLogin management.json | grep 'true'
|
||||||
|
grep LoginFlag management.json | grep 0
|
||||||
|
|
||||||
- name: Install modules
|
- name: Install modules
|
||||||
run: go mod tidy
|
run: go mod tidy
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -98,11 +99,11 @@ var loginCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
loginRequest := proto.LoginRequest{
|
loginRequest := proto.LoginRequest{
|
||||||
SetupKey: providedSetupKey,
|
SetupKey: providedSetupKey,
|
||||||
ManagementUrl: managementURL,
|
ManagementUrl: managementURL,
|
||||||
IsLinuxDesktopClient: isLinuxRunningDesktop(),
|
IsUnixDesktopClient: isUnixRunningDesktop(),
|
||||||
Hostname: hostName,
|
Hostname: hostName,
|
||||||
DnsLabels: dnsLabelsReq,
|
DnsLabels: dnsLabelsReq,
|
||||||
}
|
}
|
||||||
|
|
||||||
if rootCmd.PersistentFlags().Changed(preSharedKeyFlag) {
|
if rootCmd.PersistentFlags().Changed(preSharedKeyFlag) {
|
||||||
@@ -195,7 +196,7 @@ func foregroundLogin(ctx context.Context, cmd *cobra.Command, config *internal.C
|
|||||||
}
|
}
|
||||||
|
|
||||||
func foregroundGetTokenInfo(ctx context.Context, cmd *cobra.Command, config *internal.Config) (*auth.TokenInfo, error) {
|
func foregroundGetTokenInfo(ctx context.Context, cmd *cobra.Command, config *internal.Config) (*auth.TokenInfo, error) {
|
||||||
oAuthFlow, err := auth.NewOAuthFlow(ctx, config, isLinuxRunningDesktop())
|
oAuthFlow, err := auth.NewOAuthFlow(ctx, config, isUnixRunningDesktop())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -243,7 +244,10 @@ func openURL(cmd *cobra.Command, verificationURIComplete, userCode string, noBro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// isLinuxRunningDesktop checks if a Linux OS is running desktop environment
|
// isUnixRunningDesktop checks if a Linux OS is running desktop environment
|
||||||
func isLinuxRunningDesktop() bool {
|
func isUnixRunningDesktop() bool {
|
||||||
|
if runtime.GOOS != "linux" && runtime.GOOS != "freebsd" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return os.Getenv("DESKTOP_SESSION") != "" || os.Getenv("XDG_CURRENT_DESKTOP") != ""
|
return os.Getenv("DESKTOP_SESSION") != "" || os.Getenv("XDG_CURRENT_DESKTOP") != ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -262,17 +262,17 @@ func runInDaemonMode(ctx context.Context, cmd *cobra.Command) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loginRequest := proto.LoginRequest{
|
loginRequest := proto.LoginRequest{
|
||||||
SetupKey: providedSetupKey,
|
SetupKey: providedSetupKey,
|
||||||
ManagementUrl: managementURL,
|
ManagementUrl: managementURL,
|
||||||
AdminURL: adminURL,
|
AdminURL: adminURL,
|
||||||
NatExternalIPs: natExternalIPs,
|
NatExternalIPs: natExternalIPs,
|
||||||
CleanNATExternalIPs: natExternalIPs != nil && len(natExternalIPs) == 0,
|
CleanNATExternalIPs: natExternalIPs != nil && len(natExternalIPs) == 0,
|
||||||
CustomDNSAddress: customDNSAddressConverted,
|
CustomDNSAddress: customDNSAddressConverted,
|
||||||
IsLinuxDesktopClient: isLinuxRunningDesktop(),
|
IsUnixDesktopClient: isUnixRunningDesktop(),
|
||||||
Hostname: hostName,
|
Hostname: hostName,
|
||||||
ExtraIFaceBlacklist: extraIFaceBlackList,
|
ExtraIFaceBlacklist: extraIFaceBlackList,
|
||||||
DnsLabels: dnsLabels,
|
DnsLabels: dnsLabels,
|
||||||
CleanDNSLabels: dnsLabels != nil && len(dnsLabels) == 0,
|
CleanDNSLabels: dnsLabels != nil && len(dnsLabels) == 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
if rootCmd.PersistentFlags().Changed(preSharedKeyFlag) {
|
if rootCmd.PersistentFlags().Changed(preSharedKeyFlag) {
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
!define AUTOSTART_REG_KEY "Software\Microsoft\Windows\CurrentVersion\Run"
|
!define AUTOSTART_REG_KEY "Software\Microsoft\Windows\CurrentVersion\Run"
|
||||||
|
|
||||||
|
!define NETBIRD_DATA_DIR "$COMMONPROGRAMDATA\Netbird"
|
||||||
|
|
||||||
Unicode True
|
Unicode True
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
@@ -49,6 +51,10 @@ ShowInstDetails Show
|
|||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
|
!include "MUI2.nsh"
|
||||||
|
!include LogicLib.nsh
|
||||||
|
!include "nsDialogs.nsh"
|
||||||
|
|
||||||
!define MUI_ICON "${ICON}"
|
!define MUI_ICON "${ICON}"
|
||||||
!define MUI_UNICON "${ICON}"
|
!define MUI_UNICON "${ICON}"
|
||||||
!define MUI_WELCOMEFINISHPAGE_BITMAP "${BANNER}"
|
!define MUI_WELCOMEFINISHPAGE_BITMAP "${BANNER}"
|
||||||
@@ -58,9 +64,6 @@ ShowInstDetails Show
|
|||||||
!define MUI_FINISHPAGE_RUN_FUNCTION "LaunchLink"
|
!define MUI_FINISHPAGE_RUN_FUNCTION "LaunchLink"
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
!include "MUI2.nsh"
|
|
||||||
!include LogicLib.nsh
|
|
||||||
|
|
||||||
!define MUI_ABORTWARNING
|
!define MUI_ABORTWARNING
|
||||||
!define MUI_UNABORTWARNING
|
!define MUI_UNABORTWARNING
|
||||||
|
|
||||||
@@ -70,13 +73,16 @@ ShowInstDetails Show
|
|||||||
|
|
||||||
!insertmacro MUI_PAGE_DIRECTORY
|
!insertmacro MUI_PAGE_DIRECTORY
|
||||||
|
|
||||||
; Custom page for autostart checkbox
|
|
||||||
Page custom AutostartPage AutostartPageLeave
|
Page custom AutostartPage AutostartPageLeave
|
||||||
|
|
||||||
!insertmacro MUI_PAGE_INSTFILES
|
!insertmacro MUI_PAGE_INSTFILES
|
||||||
|
|
||||||
!insertmacro MUI_PAGE_FINISH
|
!insertmacro MUI_PAGE_FINISH
|
||||||
|
|
||||||
|
!insertmacro MUI_UNPAGE_WELCOME
|
||||||
|
|
||||||
|
UninstPage custom un.DeleteDataPage un.DeleteDataPageLeave
|
||||||
|
|
||||||
!insertmacro MUI_UNPAGE_CONFIRM
|
!insertmacro MUI_UNPAGE_CONFIRM
|
||||||
|
|
||||||
!insertmacro MUI_UNPAGE_INSTFILES
|
!insertmacro MUI_UNPAGE_INSTFILES
|
||||||
@@ -89,6 +95,10 @@ Page custom AutostartPage AutostartPageLeave
|
|||||||
Var AutostartCheckbox
|
Var AutostartCheckbox
|
||||||
Var AutostartEnabled
|
Var AutostartEnabled
|
||||||
|
|
||||||
|
; Variables for uninstall data deletion option
|
||||||
|
Var DeleteDataCheckbox
|
||||||
|
Var DeleteDataEnabled
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
; Function to create the autostart options page
|
; Function to create the autostart options page
|
||||||
@@ -104,8 +114,8 @@ Function AutostartPage
|
|||||||
|
|
||||||
${NSD_CreateCheckbox} 0 20u 100% 10u "Start ${APP_NAME} UI automatically when Windows starts"
|
${NSD_CreateCheckbox} 0 20u 100% 10u "Start ${APP_NAME} UI automatically when Windows starts"
|
||||||
Pop $AutostartCheckbox
|
Pop $AutostartCheckbox
|
||||||
${NSD_Check} $AutostartCheckbox ; Default to checked
|
${NSD_Check} $AutostartCheckbox
|
||||||
StrCpy $AutostartEnabled "1" ; Default to enabled
|
StrCpy $AutostartEnabled "1"
|
||||||
|
|
||||||
nsDialogs::Show
|
nsDialogs::Show
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
@@ -115,6 +125,30 @@ Function AutostartPageLeave
|
|||||||
${NSD_GetState} $AutostartCheckbox $AutostartEnabled
|
${NSD_GetState} $AutostartCheckbox $AutostartEnabled
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
|
||||||
|
; Function to create the uninstall data deletion page
|
||||||
|
Function un.DeleteDataPage
|
||||||
|
!insertmacro MUI_HEADER_TEXT "Uninstall Options" "Choose whether to delete ${APP_NAME} data."
|
||||||
|
|
||||||
|
nsDialogs::Create 1018
|
||||||
|
Pop $0
|
||||||
|
|
||||||
|
${If} $0 == error
|
||||||
|
Abort
|
||||||
|
${EndIf}
|
||||||
|
|
||||||
|
${NSD_CreateCheckbox} 0 20u 100% 10u "Delete all ${APP_NAME} configuration and state data (${NETBIRD_DATA_DIR})"
|
||||||
|
Pop $DeleteDataCheckbox
|
||||||
|
${NSD_Uncheck} $DeleteDataCheckbox
|
||||||
|
StrCpy $DeleteDataEnabled "0"
|
||||||
|
|
||||||
|
nsDialogs::Show
|
||||||
|
FunctionEnd
|
||||||
|
|
||||||
|
; Function to handle leaving the data deletion page
|
||||||
|
Function un.DeleteDataPageLeave
|
||||||
|
${NSD_GetState} $DeleteDataCheckbox $DeleteDataEnabled
|
||||||
|
FunctionEnd
|
||||||
|
|
||||||
Function GetAppFromCommand
|
Function GetAppFromCommand
|
||||||
Exch $1
|
Exch $1
|
||||||
Push $2
|
Push $2
|
||||||
@@ -176,10 +210,10 @@ ${EndIf}
|
|||||||
FunctionEnd
|
FunctionEnd
|
||||||
######################################################################
|
######################################################################
|
||||||
Section -MainProgram
|
Section -MainProgram
|
||||||
${INSTALL_TYPE}
|
${INSTALL_TYPE}
|
||||||
# SetOverwrite ifnewer
|
# SetOverwrite ifnewer
|
||||||
SetOutPath "$INSTDIR"
|
SetOutPath "$INSTDIR"
|
||||||
File /r "..\\dist\\netbird_windows_amd64\\"
|
File /r "..\\dist\\netbird_windows_amd64\\"
|
||||||
SectionEnd
|
SectionEnd
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
@@ -225,31 +259,58 @@ SectionEnd
|
|||||||
Section Uninstall
|
Section Uninstall
|
||||||
${INSTALL_TYPE}
|
${INSTALL_TYPE}
|
||||||
|
|
||||||
|
DetailPrint "Stopping Netbird service..."
|
||||||
ExecWait '"$INSTDIR\${MAIN_APP_EXE}" service stop'
|
ExecWait '"$INSTDIR\${MAIN_APP_EXE}" service stop'
|
||||||
|
DetailPrint "Uninstalling Netbird service..."
|
||||||
ExecWait '"$INSTDIR\${MAIN_APP_EXE}" service uninstall'
|
ExecWait '"$INSTDIR\${MAIN_APP_EXE}" service uninstall'
|
||||||
|
|
||||||
# kill ui client
|
DetailPrint "Terminating Netbird UI process..."
|
||||||
ExecWait `taskkill /im ${UI_APP_EXE}.exe /f`
|
ExecWait `taskkill /im ${UI_APP_EXE}.exe /f`
|
||||||
|
|
||||||
; Remove autostart registry entry
|
; Remove autostart registry entry
|
||||||
|
DetailPrint "Removing autostart registry entry if exists..."
|
||||||
DeleteRegValue HKCU "${AUTOSTART_REG_KEY}" "${APP_NAME}"
|
DeleteRegValue HKCU "${AUTOSTART_REG_KEY}" "${APP_NAME}"
|
||||||
|
|
||||||
|
; Handle data deletion based on checkbox
|
||||||
|
DetailPrint "Checking if user requested data deletion..."
|
||||||
|
${If} $DeleteDataEnabled == "1"
|
||||||
|
DetailPrint "User opted to delete Netbird data. Removing ${NETBIRD_DATA_DIR}..."
|
||||||
|
ClearErrors
|
||||||
|
RMDir /r "${NETBIRD_DATA_DIR}"
|
||||||
|
IfErrors 0 +2 ; If no errors, jump over the message
|
||||||
|
DetailPrint "Error deleting Netbird data directory. It might be in use or already removed."
|
||||||
|
DetailPrint "Netbird data directory removal complete."
|
||||||
|
${Else}
|
||||||
|
DetailPrint "User did not opt to delete Netbird data."
|
||||||
|
${EndIf}
|
||||||
|
|
||||||
# wait the service uninstall take unblock the executable
|
# wait the service uninstall take unblock the executable
|
||||||
|
DetailPrint "Waiting for service handle to be released..."
|
||||||
Sleep 3000
|
Sleep 3000
|
||||||
|
|
||||||
|
DetailPrint "Deleting application files..."
|
||||||
Delete "$INSTDIR\${UI_APP_EXE}"
|
Delete "$INSTDIR\${UI_APP_EXE}"
|
||||||
Delete "$INSTDIR\${MAIN_APP_EXE}"
|
Delete "$INSTDIR\${MAIN_APP_EXE}"
|
||||||
Delete "$INSTDIR\wintun.dll"
|
Delete "$INSTDIR\wintun.dll"
|
||||||
Delete "$INSTDIR\opengl32.dll"
|
Delete "$INSTDIR\opengl32.dll"
|
||||||
|
DetailPrint "Removing application directory..."
|
||||||
RmDir /r "$INSTDIR"
|
RmDir /r "$INSTDIR"
|
||||||
|
|
||||||
|
DetailPrint "Removing shortcuts..."
|
||||||
SetShellVarContext all
|
SetShellVarContext all
|
||||||
Delete "$DESKTOP\${APP_NAME}.lnk"
|
Delete "$DESKTOP\${APP_NAME}.lnk"
|
||||||
Delete "$SMPROGRAMS\${APP_NAME}.lnk"
|
Delete "$SMPROGRAMS\${APP_NAME}.lnk"
|
||||||
|
|
||||||
|
DetailPrint "Removing registry keys..."
|
||||||
DeleteRegKey ${REG_ROOT} "${REG_APP_PATH}"
|
DeleteRegKey ${REG_ROOT} "${REG_APP_PATH}"
|
||||||
DeleteRegKey ${REG_ROOT} "${UNINSTALL_PATH}"
|
DeleteRegKey ${REG_ROOT} "${UNINSTALL_PATH}"
|
||||||
|
DeleteRegKey ${REG_ROOT} "${UI_REG_APP_PATH}"
|
||||||
|
|
||||||
|
DetailPrint "Removing application directory from PATH..."
|
||||||
EnVar::SetHKLM
|
EnVar::SetHKLM
|
||||||
EnVar::DeleteValue "path" "$INSTDIR"
|
EnVar::DeleteValue "path" "$INSTDIR"
|
||||||
|
|
||||||
|
DetailPrint "Uninstallation finished."
|
||||||
SectionEnd
|
SectionEnd
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -64,13 +64,8 @@ func (t TokenInfo) GetTokenToUse() string {
|
|||||||
// and if that also fails, the authentication process is deemed unsuccessful
|
// and if that also fails, the authentication process is deemed unsuccessful
|
||||||
//
|
//
|
||||||
// On Linux distros without desktop environment support, it only tries to initialize the Device Code Flow
|
// On Linux distros without desktop environment support, it only tries to initialize the Device Code Flow
|
||||||
func NewOAuthFlow(ctx context.Context, config *internal.Config, isLinuxDesktopClient bool) (OAuthFlow, error) {
|
func NewOAuthFlow(ctx context.Context, config *internal.Config, isUnixDesktopClient bool) (OAuthFlow, error) {
|
||||||
if runtime.GOOS == "linux" && !isLinuxDesktopClient {
|
if (runtime.GOOS == "linux" || runtime.GOOS == "freebsd") && !isUnixDesktopClient {
|
||||||
return authenticateWithDeviceCodeFlow(ctx, config)
|
|
||||||
}
|
|
||||||
|
|
||||||
// On FreeBSD we currently do not support desktop environments and offer only Device Code Flow (#2384)
|
|
||||||
if runtime.GOOS == "freebsd" {
|
|
||||||
return authenticateWithDeviceCodeFlow(ctx, config)
|
return authenticateWithDeviceCodeFlow(ctx, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,12 @@ func (p *PKCEAuthorizationFlow) RequestAuthInfo(ctx context.Context) (AuthFlowIn
|
|||||||
oauth2.SetAuthURLParam("audience", p.providerConfig.Audience),
|
oauth2.SetAuthURLParam("audience", p.providerConfig.Audience),
|
||||||
}
|
}
|
||||||
if !p.providerConfig.DisablePromptLogin {
|
if !p.providerConfig.DisablePromptLogin {
|
||||||
params = append(params, oauth2.SetAuthURLParam("prompt", "login"))
|
if p.providerConfig.LoginFlag.IsPromptLogin() {
|
||||||
|
params = append(params, oauth2.SetAuthURLParam("prompt", "login"))
|
||||||
|
}
|
||||||
|
if p.providerConfig.LoginFlag.IsMaxAge0Login() {
|
||||||
|
params = append(params, oauth2.SetAuthURLParam("max_age", "0"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
authURL := p.oAuthConfig.AuthCodeURL(state, params...)
|
authURL := p.oAuthConfig.AuthCodeURL(state, params...)
|
||||||
|
|||||||
@@ -7,15 +7,36 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/client/internal"
|
"github.com/netbirdio/netbird/client/internal"
|
||||||
|
mgm "github.com/netbirdio/netbird/management/client/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestPromptLogin(t *testing.T) {
|
func TestPromptLogin(t *testing.T) {
|
||||||
|
const (
|
||||||
|
promptLogin = "prompt=login"
|
||||||
|
maxAge0 = "max_age=0"
|
||||||
|
)
|
||||||
|
|
||||||
tt := []struct {
|
tt := []struct {
|
||||||
name string
|
name string
|
||||||
prompt bool
|
loginFlag mgm.LoginFlag
|
||||||
|
disablePromptLogin bool
|
||||||
|
expect string
|
||||||
}{
|
}{
|
||||||
{"PromptLogin", true},
|
{
|
||||||
{"NoPromptLogin", false},
|
name: "Prompt login",
|
||||||
|
loginFlag: mgm.LoginFlagPrompt,
|
||||||
|
expect: promptLogin,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Max age 0 login",
|
||||||
|
loginFlag: mgm.LoginFlagMaxAge0,
|
||||||
|
expect: maxAge0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Disable prompt login",
|
||||||
|
loginFlag: mgm.LoginFlagPrompt,
|
||||||
|
disablePromptLogin: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range tt {
|
for _, tc := range tt {
|
||||||
@@ -28,7 +49,7 @@ func TestPromptLogin(t *testing.T) {
|
|||||||
AuthorizationEndpoint: "https://test-auth-endpoint.com/authorize",
|
AuthorizationEndpoint: "https://test-auth-endpoint.com/authorize",
|
||||||
RedirectURLs: []string{"http://127.0.0.1:33992/"},
|
RedirectURLs: []string{"http://127.0.0.1:33992/"},
|
||||||
UseIDToken: true,
|
UseIDToken: true,
|
||||||
DisablePromptLogin: !tc.prompt,
|
LoginFlag: tc.loginFlag,
|
||||||
}
|
}
|
||||||
pkce, err := NewPKCEAuthorizationFlow(config)
|
pkce, err := NewPKCEAuthorizationFlow(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -38,11 +59,12 @@ func TestPromptLogin(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to request auth info: %v", err)
|
t.Fatalf("Failed to request auth info: %v", err)
|
||||||
}
|
}
|
||||||
pattern := "prompt=login"
|
|
||||||
if tc.prompt {
|
if !tc.disablePromptLogin {
|
||||||
require.Contains(t, authInfo.VerificationURIComplete, pattern)
|
require.Contains(t, authInfo.VerificationURIComplete, tc.expect)
|
||||||
} else {
|
} else {
|
||||||
require.NotContains(t, authInfo.VerificationURIComplete, pattern)
|
require.Contains(t, authInfo.VerificationURIComplete, promptLogin)
|
||||||
|
require.NotContains(t, authInfo.VerificationURIComplete, maxAge0)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,9 +30,12 @@ const (
|
|||||||
systemdDbusSetDNSMethodSuffix = systemdDbusLinkInterface + ".SetDNS"
|
systemdDbusSetDNSMethodSuffix = systemdDbusLinkInterface + ".SetDNS"
|
||||||
systemdDbusSetDefaultRouteMethodSuffix = systemdDbusLinkInterface + ".SetDefaultRoute"
|
systemdDbusSetDefaultRouteMethodSuffix = systemdDbusLinkInterface + ".SetDefaultRoute"
|
||||||
systemdDbusSetDomainsMethodSuffix = systemdDbusLinkInterface + ".SetDomains"
|
systemdDbusSetDomainsMethodSuffix = systemdDbusLinkInterface + ".SetDomains"
|
||||||
|
systemdDbusSetDNSSECMethodSuffix = systemdDbusLinkInterface + ".SetDNSSEC"
|
||||||
systemdDbusResolvConfModeForeign = "foreign"
|
systemdDbusResolvConfModeForeign = "foreign"
|
||||||
|
|
||||||
dbusErrorUnknownObject = "org.freedesktop.DBus.Error.UnknownObject"
|
dbusErrorUnknownObject = "org.freedesktop.DBus.Error.UnknownObject"
|
||||||
|
|
||||||
|
dnsSecDisabled = "no"
|
||||||
)
|
)
|
||||||
|
|
||||||
type systemdDbusConfigurator struct {
|
type systemdDbusConfigurator struct {
|
||||||
@@ -95,9 +98,13 @@ func (s *systemdDbusConfigurator) applyDNSConfig(config HostDNSConfig, stateMana
|
|||||||
Family: unix.AF_INET,
|
Family: unix.AF_INET,
|
||||||
Address: ipAs4[:],
|
Address: ipAs4[:],
|
||||||
}
|
}
|
||||||
err = s.callLinkMethod(systemdDbusSetDNSMethodSuffix, []systemdDbusDNSInput{defaultLinkInput})
|
if err = s.callLinkMethod(systemdDbusSetDNSMethodSuffix, []systemdDbusDNSInput{defaultLinkInput}); err != nil {
|
||||||
if err != nil {
|
return fmt.Errorf("set interface DNS server %s:%d: %w", config.ServerIP, config.ServerPort, err)
|
||||||
return fmt.Errorf("setting the interface DNS server %s:%d failed with error: %w", config.ServerIP, config.ServerPort, err)
|
}
|
||||||
|
|
||||||
|
// We don't support dnssec. On some machines this is default on so we explicitly set it to off
|
||||||
|
if err = s.callLinkMethod(systemdDbusSetDNSSECMethodSuffix, dnsSecDisabled); err != nil {
|
||||||
|
log.Warnf("failed to set DNSSEC to 'no': %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
mgm "github.com/netbirdio/netbird/management/client"
|
mgm "github.com/netbirdio/netbird/management/client"
|
||||||
|
"github.com/netbirdio/netbird/management/client/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PKCEAuthorizationFlow represents PKCE Authorization Flow information
|
// PKCEAuthorizationFlow represents PKCE Authorization Flow information
|
||||||
@@ -41,6 +42,8 @@ type PKCEAuthProviderConfig struct {
|
|||||||
ClientCertPair *tls.Certificate
|
ClientCertPair *tls.Certificate
|
||||||
// DisablePromptLogin makes the PKCE flow to not prompt the user for login
|
// DisablePromptLogin makes the PKCE flow to not prompt the user for login
|
||||||
DisablePromptLogin bool
|
DisablePromptLogin bool
|
||||||
|
// LoginFlag is used to configure the PKCE flow login behavior
|
||||||
|
LoginFlag common.LoginFlag
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPKCEAuthorizationFlowInfo initialize a PKCEAuthorizationFlow instance and return with it
|
// GetPKCEAuthorizationFlowInfo initialize a PKCEAuthorizationFlow instance and return with it
|
||||||
@@ -100,6 +103,7 @@ func GetPKCEAuthorizationFlowInfo(ctx context.Context, privateKey string, mgmURL
|
|||||||
UseIDToken: protoPKCEAuthorizationFlow.GetProviderConfig().GetUseIDToken(),
|
UseIDToken: protoPKCEAuthorizationFlow.GetProviderConfig().GetUseIDToken(),
|
||||||
ClientCertPair: clientCert,
|
ClientCertPair: clientCert,
|
||||||
DisablePromptLogin: protoPKCEAuthorizationFlow.GetProviderConfig().GetDisablePromptLogin(),
|
DisablePromptLogin: protoPKCEAuthorizationFlow.GetProviderConfig().GetDisablePromptLogin(),
|
||||||
|
LoginFlag: common.LoginFlag(protoPKCEAuthorizationFlow.GetProviderConfig().GetLoginFlag()),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,10 @@ func (n *Notifier) SetListener(listener listener.NetworkChangeListener) {
|
|||||||
func (n *Notifier) SetInitialClientRoutes(clientRoutes []*route.Route) {
|
func (n *Notifier) SetInitialClientRoutes(clientRoutes []*route.Route) {
|
||||||
nets := make([]string, 0)
|
nets := make([]string, 0)
|
||||||
for _, r := range clientRoutes {
|
for _, r := range clientRoutes {
|
||||||
|
// filter out domain routes
|
||||||
|
if r.IsDynamic() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
nets = append(nets, r.Network.String())
|
nets = append(nets, r.Network.String())
|
||||||
}
|
}
|
||||||
sort.Strings(nets)
|
sort.Strings(nets)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -94,7 +94,7 @@ message LoginRequest {
|
|||||||
|
|
||||||
bytes customDNSAddress = 7;
|
bytes customDNSAddress = 7;
|
||||||
|
|
||||||
bool isLinuxDesktopClient = 8;
|
bool isUnixDesktopClient = 8;
|
||||||
|
|
||||||
string hostname = 9;
|
string hostname = 9;
|
||||||
|
|
||||||
|
|||||||
@@ -446,7 +446,7 @@ func (s *Server) Login(callerCtx context.Context, msg *proto.LoginRequest) (*pro
|
|||||||
state.Set(internal.StatusConnecting)
|
state.Set(internal.StatusConnecting)
|
||||||
|
|
||||||
if msg.SetupKey == "" {
|
if msg.SetupKey == "" {
|
||||||
oAuthFlow, err := auth.NewOAuthFlow(ctx, config, msg.IsLinuxDesktopClient)
|
oAuthFlow, err := auth.NewOAuthFlow(ctx, config, msg.IsUnixDesktopClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
state.Set(internal.StatusLoginFailed)
|
state.Set(internal.StatusLoginFailed)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -382,12 +382,12 @@ func (s *serviceClient) getSettingsForm() *widget.Form {
|
|||||||
s.adminURL = iAdminURL
|
s.adminURL = iAdminURL
|
||||||
|
|
||||||
loginRequest := proto.LoginRequest{
|
loginRequest := proto.LoginRequest{
|
||||||
ManagementUrl: iMngURL,
|
ManagementUrl: iMngURL,
|
||||||
AdminURL: iAdminURL,
|
AdminURL: iAdminURL,
|
||||||
IsLinuxDesktopClient: runtime.GOOS == "linux",
|
IsUnixDesktopClient: runtime.GOOS == "linux" || runtime.GOOS == "freebsd",
|
||||||
RosenpassPermissive: &s.sRosenpassPermissive.Checked,
|
RosenpassPermissive: &s.sRosenpassPermissive.Checked,
|
||||||
InterfaceName: &s.iInterfaceName.Text,
|
InterfaceName: &s.iInterfaceName.Text,
|
||||||
WireguardPort: &port,
|
WireguardPort: &port,
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.iPreSharedKey.Text != censoredPreSharedKey {
|
if s.iPreSharedKey.Text != censoredPreSharedKey {
|
||||||
@@ -414,7 +414,7 @@ func (s *serviceClient) login() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loginResp, err := conn.Login(s.ctx, &proto.LoginRequest{
|
loginResp, err := conn.Login(s.ctx, &proto.LoginRequest{
|
||||||
IsLinuxDesktopClient: runtime.GOOS == "linux",
|
IsUnixDesktopClient: runtime.GOOS == "linux" || runtime.GOOS == "freebsd",
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("login to management URL with: %v", err)
|
log.Errorf("login to management URL with: %v", err)
|
||||||
@@ -1020,7 +1020,7 @@ func (s *serviceClient) updateConfig() error {
|
|||||||
notificationsDisabled := !s.mNotifications.Checked()
|
notificationsDisabled := !s.mNotifications.Checked()
|
||||||
|
|
||||||
loginRequest := proto.LoginRequest{
|
loginRequest := proto.LoginRequest{
|
||||||
IsLinuxDesktopClient: runtime.GOOS == "linux",
|
IsUnixDesktopClient: runtime.GOOS == "linux" || runtime.GOOS == "freebsd",
|
||||||
ServerSSHAllowed: &sshAllowed,
|
ServerSSHAllowed: &sshAllowed,
|
||||||
RosenpassEnabled: &rosenpassEnabled,
|
RosenpassEnabled: &rosenpassEnabled,
|
||||||
DisableAutoConnect: &disableAutoStart,
|
DisableAutoConnect: &disableAutoStart,
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -65,7 +65,7 @@ require (
|
|||||||
github.com/mitchellh/hashstructure/v2 v2.0.2
|
github.com/mitchellh/hashstructure/v2 v2.0.2
|
||||||
github.com/nadoo/ipset v0.5.0
|
github.com/nadoo/ipset v0.5.0
|
||||||
github.com/netbirdio/management-integrations/integrations v0.0.0-20250330143713-7901e0a82203
|
github.com/netbirdio/management-integrations/integrations v0.0.0-20250330143713-7901e0a82203
|
||||||
github.com/netbirdio/signal-dispatcher/dispatcher v0.0.0-20241010133937-e0df50df217d
|
github.com/netbirdio/signal-dispatcher/dispatcher v0.0.0-20250514131221-a464fd5f30cb
|
||||||
github.com/okta/okta-sdk-golang/v2 v2.18.0
|
github.com/okta/okta-sdk-golang/v2 v2.18.0
|
||||||
github.com/oschwald/maxminddb-golang v1.12.0
|
github.com/oschwald/maxminddb-golang v1.12.0
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -507,8 +507,8 @@ github.com/netbirdio/management-integrations/integrations v0.0.0-20250330143713-
|
|||||||
github.com/netbirdio/management-integrations/integrations v0.0.0-20250330143713-7901e0a82203/go.mod h1:2ZE6/tBBCKHQggPfO2UOQjyjXI7k+JDVl2ymorTOVQs=
|
github.com/netbirdio/management-integrations/integrations v0.0.0-20250330143713-7901e0a82203/go.mod h1:2ZE6/tBBCKHQggPfO2UOQjyjXI7k+JDVl2ymorTOVQs=
|
||||||
github.com/netbirdio/service v0.0.0-20240911161631-f62744f42502 h1:3tHlFmhTdX9axERMVN63dqyFqnvuD+EMJHzM7mNGON8=
|
github.com/netbirdio/service v0.0.0-20240911161631-f62744f42502 h1:3tHlFmhTdX9axERMVN63dqyFqnvuD+EMJHzM7mNGON8=
|
||||||
github.com/netbirdio/service v0.0.0-20240911161631-f62744f42502/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM=
|
github.com/netbirdio/service v0.0.0-20240911161631-f62744f42502/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM=
|
||||||
github.com/netbirdio/signal-dispatcher/dispatcher v0.0.0-20241010133937-e0df50df217d h1:bRq5TKgC7Iq20pDiuC54yXaWnAVeS5PdGpSokFTlR28=
|
github.com/netbirdio/signal-dispatcher/dispatcher v0.0.0-20250514131221-a464fd5f30cb h1:Cr6age+ePALqlSvtp7wc6lYY97XN7rkD1K4XEDmY+TU=
|
||||||
github.com/netbirdio/signal-dispatcher/dispatcher v0.0.0-20241010133937-e0df50df217d/go.mod h1:5/sjFmLb8O96B5737VCqhHyGRzNFIaN/Bu7ZodXc3qQ=
|
github.com/netbirdio/signal-dispatcher/dispatcher v0.0.0-20250514131221-a464fd5f30cb/go.mod h1:5/sjFmLb8O96B5737VCqhHyGRzNFIaN/Bu7ZodXc3qQ=
|
||||||
github.com/netbirdio/wireguard-go v0.0.0-20241230120307-6a676aebaaf6 h1:X5h5QgP7uHAv78FWgHV8+WYLjHxK9v3ilkVXT1cpCrQ=
|
github.com/netbirdio/wireguard-go v0.0.0-20241230120307-6a676aebaaf6 h1:X5h5QgP7uHAv78FWgHV8+WYLjHxK9v3ilkVXT1cpCrQ=
|
||||||
github.com/netbirdio/wireguard-go v0.0.0-20241230120307-6a676aebaaf6/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
|
github.com/netbirdio/wireguard-go v0.0.0-20241230120307-6a676aebaaf6/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
|
github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ NETBIRD_TOKEN_SOURCE=${NETBIRD_TOKEN_SOURCE:-accessToken}
|
|||||||
NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS=${NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS:-"53000"}
|
NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS=${NETBIRD_AUTH_PKCE_REDIRECT_URL_PORTS:-"53000"}
|
||||||
NETBIRD_AUTH_PKCE_USE_ID_TOKEN=${NETBIRD_AUTH_PKCE_USE_ID_TOKEN:-false}
|
NETBIRD_AUTH_PKCE_USE_ID_TOKEN=${NETBIRD_AUTH_PKCE_USE_ID_TOKEN:-false}
|
||||||
NETBIRD_AUTH_PKCE_DISABLE_PROMPT_LOGIN=${NETBIRD_AUTH_PKCE_DISABLE_PROMPT_LOGIN:-false}
|
NETBIRD_AUTH_PKCE_DISABLE_PROMPT_LOGIN=${NETBIRD_AUTH_PKCE_DISABLE_PROMPT_LOGIN:-false}
|
||||||
|
NETBIRD_AUTH_PKCE_LOGIN_FLAG=${NETBIRD_AUTH_PKCE_LOGIN_FLAG:-1}
|
||||||
NETBIRD_AUTH_PKCE_AUDIENCE=$NETBIRD_AUTH_AUDIENCE
|
NETBIRD_AUTH_PKCE_AUDIENCE=$NETBIRD_AUTH_AUDIENCE
|
||||||
|
|
||||||
# Dashboard
|
# Dashboard
|
||||||
@@ -122,6 +123,7 @@ export NETBIRD_AUTH_DEVICE_AUTH_USE_ID_TOKEN
|
|||||||
export NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT
|
export NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT
|
||||||
export NETBIRD_AUTH_PKCE_USE_ID_TOKEN
|
export NETBIRD_AUTH_PKCE_USE_ID_TOKEN
|
||||||
export NETBIRD_AUTH_PKCE_DISABLE_PROMPT_LOGIN
|
export NETBIRD_AUTH_PKCE_DISABLE_PROMPT_LOGIN
|
||||||
|
export NETBIRD_AUTH_PKCE_LOGIN_FLAG
|
||||||
export NETBIRD_AUTH_PKCE_AUDIENCE
|
export NETBIRD_AUTH_PKCE_AUDIENCE
|
||||||
export NETBIRD_DASH_AUTH_USE_AUDIENCE
|
export NETBIRD_DASH_AUTH_USE_AUDIENCE
|
||||||
export NETBIRD_DASH_AUTH_AUDIENCE
|
export NETBIRD_DASH_AUTH_AUDIENCE
|
||||||
|
|||||||
@@ -95,7 +95,8 @@
|
|||||||
"Scope": "$NETBIRD_AUTH_SUPPORTED_SCOPES",
|
"Scope": "$NETBIRD_AUTH_SUPPORTED_SCOPES",
|
||||||
"RedirectURLs": [$NETBIRD_AUTH_PKCE_REDIRECT_URLS],
|
"RedirectURLs": [$NETBIRD_AUTH_PKCE_REDIRECT_URLS],
|
||||||
"UseIDToken": $NETBIRD_AUTH_PKCE_USE_ID_TOKEN,
|
"UseIDToken": $NETBIRD_AUTH_PKCE_USE_ID_TOKEN,
|
||||||
"DisablePromptLogin": $NETBIRD_AUTH_PKCE_DISABLE_PROMPT_LOGIN
|
"DisablePromptLogin": $NETBIRD_AUTH_PKCE_DISABLE_PROMPT_LOGIN,
|
||||||
|
"LoginFlag": $NETBIRD_AUTH_PKCE_LOGIN_FLAG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,3 +28,4 @@ NETBIRD_MGMT_IDP_SIGNKEY_REFRESH=$CI_NETBIRD_MGMT_IDP_SIGNKEY_REFRESH
|
|||||||
NETBIRD_TURN_EXTERNAL_IP=1.2.3.4
|
NETBIRD_TURN_EXTERNAL_IP=1.2.3.4
|
||||||
NETBIRD_RELAY_PORT=33445
|
NETBIRD_RELAY_PORT=33445
|
||||||
NETBIRD_AUTH_PKCE_DISABLE_PROMPT_LOGIN=true
|
NETBIRD_AUTH_PKCE_DISABLE_PROMPT_LOGIN=true
|
||||||
|
NETBIRD_AUTH_PKCE_LOGIN_FLAG=0
|
||||||
|
|||||||
19
management/client/common/types.go
Normal file
19
management/client/common/types.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
// LoginFlag introduces additional login flags to the PKCE authorization request
|
||||||
|
type LoginFlag uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
// LoginFlagPrompt adds prompt=login to the authorization request
|
||||||
|
LoginFlagPrompt LoginFlag = iota
|
||||||
|
// LoginFlagMaxAge0 adds max_age=0 to the authorization request
|
||||||
|
LoginFlagMaxAge0
|
||||||
|
)
|
||||||
|
|
||||||
|
func (l LoginFlag) IsPromptLogin() bool {
|
||||||
|
return l == LoginFlagPrompt
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l LoginFlag) IsMaxAge0Login() bool {
|
||||||
|
return l == LoginFlagMaxAge0
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ type AccountsAPI struct {
|
|||||||
// List list all accounts, only returns one account always
|
// List list all accounts, only returns one account always
|
||||||
// See more: https://docs.netbird.io/api/resources/accounts#list-all-accounts
|
// See more: https://docs.netbird.io/api/resources/accounts#list-all-accounts
|
||||||
func (a *AccountsAPI) List(ctx context.Context) ([]api.Account, error) {
|
func (a *AccountsAPI) List(ctx context.Context) ([]api.Account, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/accounts", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/accounts", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ func (a *AccountsAPI) Update(ctx context.Context, accountID string, request api.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/accounts/"+accountID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/accounts/"+accountID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (a *AccountsAPI) Update(ctx context.Context, accountID string, request api.
|
|||||||
// Delete delete account
|
// Delete delete account
|
||||||
// See more: https://docs.netbird.io/api/resources/accounts#delete-an-account
|
// See more: https://docs.netbird.io/api/resources/accounts#delete-an-account
|
||||||
func (a *AccountsAPI) Delete(ctx context.Context, accountID string) error {
|
func (a *AccountsAPI) Delete(ctx context.Context, accountID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/accounts/"+accountID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/accounts/"+accountID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
type Client struct {
|
type Client struct {
|
||||||
managementURL string
|
managementURL string
|
||||||
authHeader string
|
authHeader string
|
||||||
|
httpClient HttpClient
|
||||||
|
|
||||||
// Accounts NetBird account APIs
|
// Accounts NetBird account APIs
|
||||||
// see more: https://docs.netbird.io/api/resources/accounts
|
// see more: https://docs.netbird.io/api/resources/accounts
|
||||||
@@ -70,20 +71,29 @@ type Client struct {
|
|||||||
|
|
||||||
// New initialize new Client instance using PAT token
|
// New initialize new Client instance using PAT token
|
||||||
func New(managementURL, token string) *Client {
|
func New(managementURL, token string) *Client {
|
||||||
client := &Client{
|
return NewWithOptions(
|
||||||
managementURL: managementURL,
|
WithManagementURL(managementURL),
|
||||||
authHeader: "Token " + token,
|
WithPAT(token),
|
||||||
}
|
)
|
||||||
client.initialize()
|
|
||||||
return client
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewWithBearerToken initialize new Client instance using Bearer token type
|
// NewWithBearerToken initialize new Client instance using Bearer token type
|
||||||
func NewWithBearerToken(managementURL, token string) *Client {
|
func NewWithBearerToken(managementURL, token string) *Client {
|
||||||
|
return NewWithOptions(
|
||||||
|
WithManagementURL(managementURL),
|
||||||
|
WithBearerToken(token),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWithOptions(opts ...option) *Client {
|
||||||
client := &Client{
|
client := &Client{
|
||||||
managementURL: managementURL,
|
httpClient: http.DefaultClient,
|
||||||
authHeader: "Bearer " + token,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, option := range opts {
|
||||||
|
option(client)
|
||||||
|
}
|
||||||
|
|
||||||
client.initialize()
|
client.initialize()
|
||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
@@ -104,7 +114,7 @@ func (c *Client) initialize() {
|
|||||||
c.Events = &EventsAPI{c}
|
c.Events = &EventsAPI{c}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) newRequest(ctx context.Context, method, path string, body io.Reader) (*http.Response, error) {
|
func (c *Client) NewRequest(ctx context.Context, method, path string, body io.Reader) (*http.Response, error) {
|
||||||
req, err := http.NewRequestWithContext(ctx, method, c.managementURL+path, body)
|
req, err := http.NewRequestWithContext(ctx, method, c.managementURL+path, body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -116,7 +126,7 @@ func (c *Client) newRequest(ctx context.Context, method, path string, body io.Re
|
|||||||
req.Header.Add("Content-Type", "application/json")
|
req.Header.Add("Content-Type", "application/json")
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := c.httpClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type DNSAPI struct {
|
|||||||
// ListNameserverGroups list all nameserver groups
|
// ListNameserverGroups list all nameserver groups
|
||||||
// See more: https://docs.netbird.io/api/resources/dns#list-all-nameserver-groups
|
// See more: https://docs.netbird.io/api/resources/dns#list-all-nameserver-groups
|
||||||
func (a *DNSAPI) ListNameserverGroups(ctx context.Context) ([]api.NameserverGroup, error) {
|
func (a *DNSAPI) ListNameserverGroups(ctx context.Context) ([]api.NameserverGroup, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/dns/nameservers", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/dns/nameservers", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ func (a *DNSAPI) ListNameserverGroups(ctx context.Context) ([]api.NameserverGrou
|
|||||||
// GetNameserverGroup get nameserver group info
|
// GetNameserverGroup get nameserver group info
|
||||||
// See more: https://docs.netbird.io/api/resources/dns#retrieve-a-nameserver-group
|
// See more: https://docs.netbird.io/api/resources/dns#retrieve-a-nameserver-group
|
||||||
func (a *DNSAPI) GetNameserverGroup(ctx context.Context, nameserverGroupID string) (*api.NameserverGroup, error) {
|
func (a *DNSAPI) GetNameserverGroup(ctx context.Context, nameserverGroupID string) (*api.NameserverGroup, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/dns/nameservers/"+nameserverGroupID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/dns/nameservers/"+nameserverGroupID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (a *DNSAPI) CreateNameserverGroup(ctx context.Context, request api.PostApiD
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/dns/nameservers", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/dns/nameservers", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ func (a *DNSAPI) UpdateNameserverGroup(ctx context.Context, nameserverGroupID st
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/dns/nameservers/"+nameserverGroupID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/dns/nameservers/"+nameserverGroupID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ func (a *DNSAPI) UpdateNameserverGroup(ctx context.Context, nameserverGroupID st
|
|||||||
// DeleteNameserverGroup delete nameserver group
|
// DeleteNameserverGroup delete nameserver group
|
||||||
// See more: https://docs.netbird.io/api/resources/dns#delete-a-nameserver-group
|
// See more: https://docs.netbird.io/api/resources/dns#delete-a-nameserver-group
|
||||||
func (a *DNSAPI) DeleteNameserverGroup(ctx context.Context, nameserverGroupID string) error {
|
func (a *DNSAPI) DeleteNameserverGroup(ctx context.Context, nameserverGroupID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/dns/nameservers/"+nameserverGroupID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/dns/nameservers/"+nameserverGroupID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ func (a *DNSAPI) DeleteNameserverGroup(ctx context.Context, nameserverGroupID st
|
|||||||
// GetSettings get DNS settings
|
// GetSettings get DNS settings
|
||||||
// See more: https://docs.netbird.io/api/resources/dns#retrieve-dns-settings
|
// See more: https://docs.netbird.io/api/resources/dns#retrieve-dns-settings
|
||||||
func (a *DNSAPI) GetSettings(ctx context.Context) (*api.DNSSettings, error) {
|
func (a *DNSAPI) GetSettings(ctx context.Context) (*api.DNSSettings, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/dns/settings", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/dns/settings", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -112,7 +112,7 @@ func (a *DNSAPI) UpdateSettings(ctx context.Context, request api.PutApiDnsSettin
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/dns/settings", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/dns/settings", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ type EventsAPI struct {
|
|||||||
// List list all events
|
// List list all events
|
||||||
// See more: https://docs.netbird.io/api/resources/events#list-all-events
|
// See more: https://docs.netbird.io/api/resources/events#list-all-events
|
||||||
func (a *EventsAPI) List(ctx context.Context) ([]api.Event, error) {
|
func (a *EventsAPI) List(ctx context.Context) ([]api.Event, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/events", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/events", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ type GeoLocationAPI struct {
|
|||||||
// ListCountries list all country codes
|
// ListCountries list all country codes
|
||||||
// See more: https://docs.netbird.io/api/resources/geo-locations#list-all-country-codes
|
// See more: https://docs.netbird.io/api/resources/geo-locations#list-all-country-codes
|
||||||
func (a *GeoLocationAPI) ListCountries(ctx context.Context) ([]api.Country, error) {
|
func (a *GeoLocationAPI) ListCountries(ctx context.Context) ([]api.Country, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/locations/countries", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/locations/countries", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ func (a *GeoLocationAPI) ListCountries(ctx context.Context) ([]api.Country, erro
|
|||||||
// ListCountryCities Get a list of all English city names for a given country code
|
// ListCountryCities Get a list of all English city names for a given country code
|
||||||
// See more: https://docs.netbird.io/api/resources/geo-locations#list-all-city-names-by-country
|
// See more: https://docs.netbird.io/api/resources/geo-locations#list-all-city-names-by-country
|
||||||
func (a *GeoLocationAPI) ListCountryCities(ctx context.Context, countryCode string) ([]api.City, error) {
|
func (a *GeoLocationAPI) ListCountryCities(ctx context.Context, countryCode string) ([]api.City, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/locations/countries/"+countryCode+"/cities", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/locations/countries/"+countryCode+"/cities", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type GroupsAPI struct {
|
|||||||
// List list all groups
|
// List list all groups
|
||||||
// See more: https://docs.netbird.io/api/resources/groups#list-all-groups
|
// See more: https://docs.netbird.io/api/resources/groups#list-all-groups
|
||||||
func (a *GroupsAPI) List(ctx context.Context) ([]api.Group, error) {
|
func (a *GroupsAPI) List(ctx context.Context) ([]api.Group, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/groups", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/groups", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ func (a *GroupsAPI) List(ctx context.Context) ([]api.Group, error) {
|
|||||||
// Get get group info
|
// Get get group info
|
||||||
// See more: https://docs.netbird.io/api/resources/groups#retrieve-a-group
|
// See more: https://docs.netbird.io/api/resources/groups#retrieve-a-group
|
||||||
func (a *GroupsAPI) Get(ctx context.Context, groupID string) (*api.Group, error) {
|
func (a *GroupsAPI) Get(ctx context.Context, groupID string) (*api.Group, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/groups/"+groupID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/groups/"+groupID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (a *GroupsAPI) Create(ctx context.Context, request api.PostApiGroupsJSONReq
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/groups", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/groups", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ func (a *GroupsAPI) Update(ctx context.Context, groupID string, request api.PutA
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/groups/"+groupID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/groups/"+groupID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ func (a *GroupsAPI) Update(ctx context.Context, groupID string, request api.PutA
|
|||||||
// Delete delete group
|
// Delete delete group
|
||||||
// See more: https://docs.netbird.io/api/resources/groups#delete-a-group
|
// See more: https://docs.netbird.io/api/resources/groups#delete-a-group
|
||||||
func (a *GroupsAPI) Delete(ctx context.Context, groupID string) error {
|
func (a *GroupsAPI) Delete(ctx context.Context, groupID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/groups/"+groupID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/groups/"+groupID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type NetworksAPI struct {
|
|||||||
// List list all networks
|
// List list all networks
|
||||||
// See more: https://docs.netbird.io/api/resources/networks#list-all-networks
|
// See more: https://docs.netbird.io/api/resources/networks#list-all-networks
|
||||||
func (a *NetworksAPI) List(ctx context.Context) ([]api.Network, error) {
|
func (a *NetworksAPI) List(ctx context.Context) ([]api.Network, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/networks", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/networks", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ func (a *NetworksAPI) List(ctx context.Context) ([]api.Network, error) {
|
|||||||
// Get get network info
|
// Get get network info
|
||||||
// See more: https://docs.netbird.io/api/resources/networks#retrieve-a-network
|
// See more: https://docs.netbird.io/api/resources/networks#retrieve-a-network
|
||||||
func (a *NetworksAPI) Get(ctx context.Context, networkID string) (*api.Network, error) {
|
func (a *NetworksAPI) Get(ctx context.Context, networkID string) (*api.Network, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/networks/"+networkID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/networks/"+networkID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (a *NetworksAPI) Create(ctx context.Context, request api.PostApiNetworksJSO
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/networks", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/networks", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ func (a *NetworksAPI) Update(ctx context.Context, networkID string, request api.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/networks/"+networkID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/networks/"+networkID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ func (a *NetworksAPI) Update(ctx context.Context, networkID string, request api.
|
|||||||
// Delete delete network
|
// Delete delete network
|
||||||
// See more: https://docs.netbird.io/api/resources/networks#delete-a-network
|
// See more: https://docs.netbird.io/api/resources/networks#delete-a-network
|
||||||
func (a *NetworksAPI) Delete(ctx context.Context, networkID string) error {
|
func (a *NetworksAPI) Delete(ctx context.Context, networkID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/networks/"+networkID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/networks/"+networkID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@ func (a *NetworksAPI) Resources(networkID string) *NetworkResourcesAPI {
|
|||||||
// List list all resources in networks
|
// List list all resources in networks
|
||||||
// See more: https://docs.netbird.io/api/resources/networks#list-all-network-resources
|
// See more: https://docs.netbird.io/api/resources/networks#list-all-network-resources
|
||||||
func (a *NetworkResourcesAPI) List(ctx context.Context) ([]api.NetworkResource, error) {
|
func (a *NetworkResourcesAPI) List(ctx context.Context) ([]api.NetworkResource, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/networks/"+a.networkID+"/resources", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/networks/"+a.networkID+"/resources", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ func (a *NetworkResourcesAPI) List(ctx context.Context) ([]api.NetworkResource,
|
|||||||
// Get get network resource info
|
// Get get network resource info
|
||||||
// See more: https://docs.netbird.io/api/resources/networks#retrieve-a-network-resource
|
// See more: https://docs.netbird.io/api/resources/networks#retrieve-a-network-resource
|
||||||
func (a *NetworkResourcesAPI) Get(ctx context.Context, networkResourceID string) (*api.NetworkResource, error) {
|
func (a *NetworkResourcesAPI) Get(ctx context.Context, networkResourceID string) (*api.NetworkResource, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/networks/"+a.networkID+"/resources/"+networkResourceID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/networks/"+a.networkID+"/resources/"+networkResourceID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,7 @@ func (a *NetworkResourcesAPI) Create(ctx context.Context, request api.PostApiNet
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/networks/"+a.networkID+"/resources", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/networks/"+a.networkID+"/resources", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -158,7 +158,7 @@ func (a *NetworkResourcesAPI) Update(ctx context.Context, networkResourceID stri
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/networks/"+a.networkID+"/resources/"+networkResourceID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/networks/"+a.networkID+"/resources/"+networkResourceID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -172,7 +172,7 @@ func (a *NetworkResourcesAPI) Update(ctx context.Context, networkResourceID stri
|
|||||||
// Delete delete network resource
|
// Delete delete network resource
|
||||||
// See more: https://docs.netbird.io/api/resources/networks#delete-a-network-resource
|
// See more: https://docs.netbird.io/api/resources/networks#delete-a-network-resource
|
||||||
func (a *NetworkResourcesAPI) Delete(ctx context.Context, networkResourceID string) error {
|
func (a *NetworkResourcesAPI) Delete(ctx context.Context, networkResourceID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/networks/"+a.networkID+"/resources/"+networkResourceID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/networks/"+a.networkID+"/resources/"+networkResourceID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -200,7 +200,7 @@ func (a *NetworksAPI) Routers(networkID string) *NetworkRoutersAPI {
|
|||||||
// List list all routers in networks
|
// List list all routers in networks
|
||||||
// See more: https://docs.netbird.io/api/routers/networks#list-all-network-routers
|
// See more: https://docs.netbird.io/api/routers/networks#list-all-network-routers
|
||||||
func (a *NetworkRoutersAPI) List(ctx context.Context) ([]api.NetworkRouter, error) {
|
func (a *NetworkRoutersAPI) List(ctx context.Context) ([]api.NetworkRouter, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/networks/"+a.networkID+"/routers", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/networks/"+a.networkID+"/routers", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -214,7 +214,7 @@ func (a *NetworkRoutersAPI) List(ctx context.Context) ([]api.NetworkRouter, erro
|
|||||||
// Get get network router info
|
// Get get network router info
|
||||||
// See more: https://docs.netbird.io/api/routers/networks#retrieve-a-network-router
|
// See more: https://docs.netbird.io/api/routers/networks#retrieve-a-network-router
|
||||||
func (a *NetworkRoutersAPI) Get(ctx context.Context, networkRouterID string) (*api.NetworkRouter, error) {
|
func (a *NetworkRoutersAPI) Get(ctx context.Context, networkRouterID string) (*api.NetworkRouter, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/networks/"+a.networkID+"/routers/"+networkRouterID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/networks/"+a.networkID+"/routers/"+networkRouterID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -232,7 +232,7 @@ func (a *NetworkRoutersAPI) Create(ctx context.Context, request api.PostApiNetwo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/networks/"+a.networkID+"/routers", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/networks/"+a.networkID+"/routers", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -250,7 +250,7 @@ func (a *NetworkRoutersAPI) Update(ctx context.Context, networkRouterID string,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/networks/"+a.networkID+"/routers/"+networkRouterID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/networks/"+a.networkID+"/routers/"+networkRouterID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -264,7 +264,7 @@ func (a *NetworkRoutersAPI) Update(ctx context.Context, networkRouterID string,
|
|||||||
// Delete delete network router
|
// Delete delete network router
|
||||||
// See more: https://docs.netbird.io/api/routers/networks#delete-a-network-router
|
// See more: https://docs.netbird.io/api/routers/networks#delete-a-network-router
|
||||||
func (a *NetworkRoutersAPI) Delete(ctx context.Context, networkRouterID string) error {
|
func (a *NetworkRoutersAPI) Delete(ctx context.Context, networkRouterID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/networks/"+a.networkID+"/routers/"+networkRouterID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/networks/"+a.networkID+"/routers/"+networkRouterID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
35
management/client/rest/options.go
Normal file
35
management/client/rest/options.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package rest
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
|
type option func(*Client)
|
||||||
|
|
||||||
|
type HttpClient interface {
|
||||||
|
Do(req *http.Request) (*http.Response, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithHttpClient(client HttpClient) option {
|
||||||
|
return func(c *Client) {
|
||||||
|
c.httpClient = client
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithBearerToken(token string) option {
|
||||||
|
return WithAuthHeader("Bearer " + token)
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithPAT(token string) option {
|
||||||
|
return WithAuthHeader("Token " + token)
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithManagementURL(url string) option {
|
||||||
|
return func(c *Client) {
|
||||||
|
c.managementURL = url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithAuthHeader(value string) option {
|
||||||
|
return func(c *Client) {
|
||||||
|
c.authHeader = value
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ type PeersAPI struct {
|
|||||||
// List list all peers
|
// List list all peers
|
||||||
// See more: https://docs.netbird.io/api/resources/peers#list-all-peers
|
// See more: https://docs.netbird.io/api/resources/peers#list-all-peers
|
||||||
func (a *PeersAPI) List(ctx context.Context) ([]api.Peer, error) {
|
func (a *PeersAPI) List(ctx context.Context) ([]api.Peer, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/peers", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/peers", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ func (a *PeersAPI) List(ctx context.Context) ([]api.Peer, error) {
|
|||||||
// Get retrieve a peer
|
// Get retrieve a peer
|
||||||
// See more: https://docs.netbird.io/api/resources/peers#retrieve-a-peer
|
// See more: https://docs.netbird.io/api/resources/peers#retrieve-a-peer
|
||||||
func (a *PeersAPI) Get(ctx context.Context, peerID string) (*api.Peer, error) {
|
func (a *PeersAPI) Get(ctx context.Context, peerID string) (*api.Peer, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/peers/"+peerID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/peers/"+peerID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (a *PeersAPI) Update(ctx context.Context, peerID string, request api.PutApi
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/peers/"+peerID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/peers/"+peerID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ func (a *PeersAPI) Update(ctx context.Context, peerID string, request api.PutApi
|
|||||||
// Delete delete a peer
|
// Delete delete a peer
|
||||||
// See more: https://docs.netbird.io/api/resources/peers#delete-a-peer
|
// See more: https://docs.netbird.io/api/resources/peers#delete-a-peer
|
||||||
func (a *PeersAPI) Delete(ctx context.Context, peerID string) error {
|
func (a *PeersAPI) Delete(ctx context.Context, peerID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/peers/"+peerID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/peers/"+peerID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ func (a *PeersAPI) Delete(ctx context.Context, peerID string) error {
|
|||||||
// ListAccessiblePeers list all peers that the specified peer can connect to within the network
|
// ListAccessiblePeers list all peers that the specified peer can connect to within the network
|
||||||
// See more: https://docs.netbird.io/api/resources/peers#list-accessible-peers
|
// See more: https://docs.netbird.io/api/resources/peers#list-accessible-peers
|
||||||
func (a *PeersAPI) ListAccessiblePeers(ctx context.Context, peerID string) ([]api.Peer, error) {
|
func (a *PeersAPI) ListAccessiblePeers(ctx context.Context, peerID string) ([]api.Peer, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/peers/"+peerID+"/accessible-peers", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/peers/"+peerID+"/accessible-peers", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ type PoliciesAPI struct {
|
|||||||
// List list all policies
|
// List list all policies
|
||||||
// See more: https://docs.netbird.io/api/resources/policies#list-all-policies
|
// See more: https://docs.netbird.io/api/resources/policies#list-all-policies
|
||||||
func (a *PoliciesAPI) List(ctx context.Context) ([]api.Policy, error) {
|
func (a *PoliciesAPI) List(ctx context.Context) ([]api.Policy, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/policies", nil)
|
path := "/api/policies"
|
||||||
|
|
||||||
|
resp, err := a.c.NewRequest(ctx, "GET", path, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +32,7 @@ func (a *PoliciesAPI) List(ctx context.Context) ([]api.Policy, error) {
|
|||||||
// Get get policy info
|
// Get get policy info
|
||||||
// See more: https://docs.netbird.io/api/resources/policies#retrieve-a-policy
|
// See more: https://docs.netbird.io/api/resources/policies#retrieve-a-policy
|
||||||
func (a *PoliciesAPI) Get(ctx context.Context, policyID string) (*api.Policy, error) {
|
func (a *PoliciesAPI) Get(ctx context.Context, policyID string) (*api.Policy, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/policies/"+policyID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/policies/"+policyID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +50,7 @@ func (a *PoliciesAPI) Create(ctx context.Context, request api.PostApiPoliciesJSO
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/policies", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/policies", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -62,11 +64,13 @@ func (a *PoliciesAPI) Create(ctx context.Context, request api.PostApiPoliciesJSO
|
|||||||
// Update update policy info
|
// Update update policy info
|
||||||
// See more: https://docs.netbird.io/api/resources/policies#update-a-policy
|
// See more: https://docs.netbird.io/api/resources/policies#update-a-policy
|
||||||
func (a *PoliciesAPI) Update(ctx context.Context, policyID string, request api.PutApiPoliciesPolicyIdJSONRequestBody) (*api.Policy, error) {
|
func (a *PoliciesAPI) Update(ctx context.Context, policyID string, request api.PutApiPoliciesPolicyIdJSONRequestBody) (*api.Policy, error) {
|
||||||
|
path := "/api/policies/" + policyID
|
||||||
|
|
||||||
requestBytes, err := json.Marshal(request)
|
requestBytes, err := json.Marshal(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/policies/"+policyID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", path, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -80,7 +84,7 @@ func (a *PoliciesAPI) Update(ctx context.Context, policyID string, request api.P
|
|||||||
// Delete delete policy
|
// Delete delete policy
|
||||||
// See more: https://docs.netbird.io/api/resources/policies#delete-a-policy
|
// See more: https://docs.netbird.io/api/resources/policies#delete-a-policy
|
||||||
func (a *PoliciesAPI) Delete(ctx context.Context, policyID string) error {
|
func (a *PoliciesAPI) Delete(ctx context.Context, policyID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/policies/"+policyID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/policies/"+policyID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type PostureChecksAPI struct {
|
|||||||
// List list all posture checks
|
// List list all posture checks
|
||||||
// See more: https://docs.netbird.io/api/resources/posture-checks#list-all-posture-checks
|
// See more: https://docs.netbird.io/api/resources/posture-checks#list-all-posture-checks
|
||||||
func (a *PostureChecksAPI) List(ctx context.Context) ([]api.PostureCheck, error) {
|
func (a *PostureChecksAPI) List(ctx context.Context) ([]api.PostureCheck, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/posture-checks", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/posture-checks", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ func (a *PostureChecksAPI) List(ctx context.Context) ([]api.PostureCheck, error)
|
|||||||
// Get get posture check info
|
// Get get posture check info
|
||||||
// See more: https://docs.netbird.io/api/resources/posture-checks#retrieve-a-posture-check
|
// See more: https://docs.netbird.io/api/resources/posture-checks#retrieve-a-posture-check
|
||||||
func (a *PostureChecksAPI) Get(ctx context.Context, postureCheckID string) (*api.PostureCheck, error) {
|
func (a *PostureChecksAPI) Get(ctx context.Context, postureCheckID string) (*api.PostureCheck, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/posture-checks/"+postureCheckID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/posture-checks/"+postureCheckID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (a *PostureChecksAPI) Create(ctx context.Context, request api.PostApiPostur
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/posture-checks", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/posture-checks", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ func (a *PostureChecksAPI) Update(ctx context.Context, postureCheckID string, re
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/posture-checks/"+postureCheckID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/posture-checks/"+postureCheckID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ func (a *PostureChecksAPI) Update(ctx context.Context, postureCheckID string, re
|
|||||||
// Delete delete posture check
|
// Delete delete posture check
|
||||||
// See more: https://docs.netbird.io/api/resources/posture-checks#delete-a-posture-check
|
// See more: https://docs.netbird.io/api/resources/posture-checks#delete-a-posture-check
|
||||||
func (a *PostureChecksAPI) Delete(ctx context.Context, postureCheckID string) error {
|
func (a *PostureChecksAPI) Delete(ctx context.Context, postureCheckID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/posture-checks/"+postureCheckID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/posture-checks/"+postureCheckID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type RoutesAPI struct {
|
|||||||
// List list all routes
|
// List list all routes
|
||||||
// See more: https://docs.netbird.io/api/resources/routes#list-all-routes
|
// See more: https://docs.netbird.io/api/resources/routes#list-all-routes
|
||||||
func (a *RoutesAPI) List(ctx context.Context) ([]api.Route, error) {
|
func (a *RoutesAPI) List(ctx context.Context) ([]api.Route, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/routes", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/routes", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ func (a *RoutesAPI) List(ctx context.Context) ([]api.Route, error) {
|
|||||||
// Get get route info
|
// Get get route info
|
||||||
// See more: https://docs.netbird.io/api/resources/routes#retrieve-a-route
|
// See more: https://docs.netbird.io/api/resources/routes#retrieve-a-route
|
||||||
func (a *RoutesAPI) Get(ctx context.Context, routeID string) (*api.Route, error) {
|
func (a *RoutesAPI) Get(ctx context.Context, routeID string) (*api.Route, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/routes/"+routeID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/routes/"+routeID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (a *RoutesAPI) Create(ctx context.Context, request api.PostApiRoutesJSONReq
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/routes", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/routes", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ func (a *RoutesAPI) Update(ctx context.Context, routeID string, request api.PutA
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/routes/"+routeID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/routes/"+routeID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ func (a *RoutesAPI) Update(ctx context.Context, routeID string, request api.PutA
|
|||||||
// Delete delete route
|
// Delete delete route
|
||||||
// See more: https://docs.netbird.io/api/resources/routes#delete-a-route
|
// See more: https://docs.netbird.io/api/resources/routes#delete-a-route
|
||||||
func (a *RoutesAPI) Delete(ctx context.Context, routeID string) error {
|
func (a *RoutesAPI) Delete(ctx context.Context, routeID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/routes/"+routeID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/routes/"+routeID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type SetupKeysAPI struct {
|
|||||||
// List list all setup keys
|
// List list all setup keys
|
||||||
// See more: https://docs.netbird.io/api/resources/setup-keys#list-all-setup-keys
|
// See more: https://docs.netbird.io/api/resources/setup-keys#list-all-setup-keys
|
||||||
func (a *SetupKeysAPI) List(ctx context.Context) ([]api.SetupKey, error) {
|
func (a *SetupKeysAPI) List(ctx context.Context) ([]api.SetupKey, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/setup-keys", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/setup-keys", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ func (a *SetupKeysAPI) List(ctx context.Context) ([]api.SetupKey, error) {
|
|||||||
// Get get setup key info
|
// Get get setup key info
|
||||||
// See more: https://docs.netbird.io/api/resources/setup-keys#retrieve-a-setup-key
|
// See more: https://docs.netbird.io/api/resources/setup-keys#retrieve-a-setup-key
|
||||||
func (a *SetupKeysAPI) Get(ctx context.Context, setupKeyID string) (*api.SetupKey, error) {
|
func (a *SetupKeysAPI) Get(ctx context.Context, setupKeyID string) (*api.SetupKey, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/setup-keys/"+setupKeyID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/setup-keys/"+setupKeyID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -44,11 +44,13 @@ func (a *SetupKeysAPI) Get(ctx context.Context, setupKeyID string) (*api.SetupKe
|
|||||||
// Create generate new Setup Key
|
// Create generate new Setup Key
|
||||||
// See more: https://docs.netbird.io/api/resources/setup-keys#create-a-setup-key
|
// See more: https://docs.netbird.io/api/resources/setup-keys#create-a-setup-key
|
||||||
func (a *SetupKeysAPI) Create(ctx context.Context, request api.PostApiSetupKeysJSONRequestBody) (*api.SetupKeyClear, error) {
|
func (a *SetupKeysAPI) Create(ctx context.Context, request api.PostApiSetupKeysJSONRequestBody) (*api.SetupKeyClear, error) {
|
||||||
|
path := "/api/setup-keys"
|
||||||
|
|
||||||
requestBytes, err := json.Marshal(request)
|
requestBytes, err := json.Marshal(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/setup-keys", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", path, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -66,7 +68,7 @@ func (a *SetupKeysAPI) Update(ctx context.Context, setupKeyID string, request ap
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/setup-keys/"+setupKeyID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/setup-keys/"+setupKeyID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -80,7 +82,7 @@ func (a *SetupKeysAPI) Update(ctx context.Context, setupKeyID string, request ap
|
|||||||
// Delete delete setup key
|
// Delete delete setup key
|
||||||
// See more: https://docs.netbird.io/api/resources/setup-keys#delete-a-setup-key
|
// See more: https://docs.netbird.io/api/resources/setup-keys#delete-a-setup-key
|
||||||
func (a *SetupKeysAPI) Delete(ctx context.Context, setupKeyID string) error {
|
func (a *SetupKeysAPI) Delete(ctx context.Context, setupKeyID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/setup-keys/"+setupKeyID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/setup-keys/"+setupKeyID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type TokensAPI struct {
|
|||||||
// List list user tokens
|
// List list user tokens
|
||||||
// See more: https://docs.netbird.io/api/resources/tokens#list-all-tokens
|
// See more: https://docs.netbird.io/api/resources/tokens#list-all-tokens
|
||||||
func (a *TokensAPI) List(ctx context.Context, userID string) ([]api.PersonalAccessToken, error) {
|
func (a *TokensAPI) List(ctx context.Context, userID string) ([]api.PersonalAccessToken, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/users/"+userID+"/tokens", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/users/"+userID+"/tokens", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ func (a *TokensAPI) List(ctx context.Context, userID string) ([]api.PersonalAcce
|
|||||||
// Get get user token info
|
// Get get user token info
|
||||||
// See more: https://docs.netbird.io/api/resources/tokens#retrieve-a-token
|
// See more: https://docs.netbird.io/api/resources/tokens#retrieve-a-token
|
||||||
func (a *TokensAPI) Get(ctx context.Context, userID, tokenID string) (*api.PersonalAccessToken, error) {
|
func (a *TokensAPI) Get(ctx context.Context, userID, tokenID string) (*api.PersonalAccessToken, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/users/"+userID+"/tokens/"+tokenID, nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/users/"+userID+"/tokens/"+tokenID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (a *TokensAPI) Create(ctx context.Context, userID string, request api.PostA
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/users/"+userID+"/tokens", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/users/"+userID+"/tokens", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ func (a *TokensAPI) Create(ctx context.Context, userID string, request api.PostA
|
|||||||
// Delete delete user token
|
// Delete delete user token
|
||||||
// See more: https://docs.netbird.io/api/resources/tokens#delete-a-token
|
// See more: https://docs.netbird.io/api/resources/tokens#delete-a-token
|
||||||
func (a *TokensAPI) Delete(ctx context.Context, userID, tokenID string) error {
|
func (a *TokensAPI) Delete(ctx context.Context, userID, tokenID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/users/"+userID+"/tokens/"+tokenID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/users/"+userID+"/tokens/"+tokenID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ type UsersAPI struct {
|
|||||||
// List list all users, only returns one user always
|
// List list all users, only returns one user always
|
||||||
// See more: https://docs.netbird.io/api/resources/users#list-all-users
|
// See more: https://docs.netbird.io/api/resources/users#list-all-users
|
||||||
func (a *UsersAPI) List(ctx context.Context) ([]api.User, error) {
|
func (a *UsersAPI) List(ctx context.Context) ([]api.User, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/users", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/users", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ func (a *UsersAPI) Create(ctx context.Context, request api.PostApiUsersJSONReque
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/users", bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/users", bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ func (a *UsersAPI) Update(ctx context.Context, userID string, request api.PutApi
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resp, err := a.c.newRequest(ctx, "PUT", "/api/users/"+userID, bytes.NewReader(requestBytes))
|
resp, err := a.c.NewRequest(ctx, "PUT", "/api/users/"+userID, bytes.NewReader(requestBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ func (a *UsersAPI) Update(ctx context.Context, userID string, request api.PutApi
|
|||||||
// Delete delete user
|
// Delete delete user
|
||||||
// See more: https://docs.netbird.io/api/resources/users#delete-a-user
|
// See more: https://docs.netbird.io/api/resources/users#delete-a-user
|
||||||
func (a *UsersAPI) Delete(ctx context.Context, userID string) error {
|
func (a *UsersAPI) Delete(ctx context.Context, userID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "DELETE", "/api/users/"+userID, nil)
|
resp, err := a.c.NewRequest(ctx, "DELETE", "/api/users/"+userID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ func (a *UsersAPI) Delete(ctx context.Context, userID string) error {
|
|||||||
// ResendInvitation resend user invitation
|
// ResendInvitation resend user invitation
|
||||||
// See more: https://docs.netbird.io/api/resources/users#resend-user-invitation
|
// See more: https://docs.netbird.io/api/resources/users#resend-user-invitation
|
||||||
func (a *UsersAPI) ResendInvitation(ctx context.Context, userID string) error {
|
func (a *UsersAPI) ResendInvitation(ctx context.Context, userID string) error {
|
||||||
resp, err := a.c.newRequest(ctx, "POST", "/api/users/"+userID+"/invite", nil)
|
resp, err := a.c.NewRequest(ctx, "POST", "/api/users/"+userID+"/invite", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,7 @@ func (a *UsersAPI) ResendInvitation(ctx context.Context, userID string) error {
|
|||||||
// Current gets the current user info
|
// Current gets the current user info
|
||||||
// See more: https://docs.netbird.io/api/resources/users#retrieve-current-user
|
// See more: https://docs.netbird.io/api/resources/users#retrieve-current-user
|
||||||
func (a *UsersAPI) Current(ctx context.Context) (*api.User, error) {
|
func (a *UsersAPI) Current(ctx context.Context) (*api.User, error) {
|
||||||
resp, err := a.c.newRequest(ctx, "GET", "/api/users/current", nil)
|
resp, err := a.c.NewRequest(ctx, "GET", "/api/users/current", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import (
|
|||||||
|
|
||||||
const maxDomains = 32
|
const maxDomains = 32
|
||||||
|
|
||||||
|
var domainRegex = regexp.MustCompile(`^(?:\*\.)?(?:(?:xn--)?[a-zA-Z0-9_](?:[a-zA-Z0-9-_]{0,61}[a-zA-Z0-9])?\.)*(?:xn--)?[a-zA-Z0-9](?:[a-zA-Z0-9-_]{0,61}[a-zA-Z0-9])?$`)
|
||||||
|
|
||||||
// ValidateDomains checks if each domain in the list is valid and returns a punycode-encoded DomainList.
|
// ValidateDomains checks if each domain in the list is valid and returns a punycode-encoded DomainList.
|
||||||
func ValidateDomains(domains []string) (List, error) {
|
func ValidateDomains(domains []string) (List, error) {
|
||||||
if len(domains) == 0 {
|
if len(domains) == 0 {
|
||||||
@@ -17,8 +19,6 @@ func ValidateDomains(domains []string) (List, error) {
|
|||||||
return nil, fmt.Errorf("domains list exceeds maximum allowed domains: %d", maxDomains)
|
return nil, fmt.Errorf("domains list exceeds maximum allowed domains: %d", maxDomains)
|
||||||
}
|
}
|
||||||
|
|
||||||
domainRegex := regexp.MustCompile(`^(?:\*\.)?(?:(?:xn--)?[a-zA-Z0-9_](?:[a-zA-Z0-9-_]{0,61}[a-zA-Z0-9])?\.)*(?:xn--)?[a-zA-Z0-9](?:[a-zA-Z0-9-_]{0,61}[a-zA-Z0-9])?$`)
|
|
||||||
|
|
||||||
var domainList List
|
var domainList List
|
||||||
|
|
||||||
for _, d := range domains {
|
for _, d := range domains {
|
||||||
@@ -37,27 +37,20 @@ func ValidateDomains(domains []string) (List, error) {
|
|||||||
return domainList, nil
|
return domainList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateDomainsStrSlice checks if each domain in the list is valid
|
// ValidateDomainsList checks if each domain in the list is valid
|
||||||
func ValidateDomainsStrSlice(domains []string) ([]string, error) {
|
func ValidateDomainsList(domains []string) error {
|
||||||
if len(domains) == 0 {
|
if len(domains) == 0 {
|
||||||
return nil, nil
|
return nil
|
||||||
}
|
}
|
||||||
if len(domains) > maxDomains {
|
if len(domains) > maxDomains {
|
||||||
return nil, fmt.Errorf("domains list exceeds maximum allowed domains: %d", maxDomains)
|
return fmt.Errorf("domains list exceeds maximum allowed domains: %d", maxDomains)
|
||||||
}
|
}
|
||||||
|
|
||||||
domainRegex := regexp.MustCompile(`^(?:\*\.)?(?:(?:xn--)?[a-zA-Z0-9_](?:[a-zA-Z0-9-_]{0,61}[a-zA-Z0-9])?\.)*(?:xn--)?[a-zA-Z0-9](?:[a-zA-Z0-9-_]{0,61}[a-zA-Z0-9])?$`)
|
|
||||||
|
|
||||||
var domainList []string
|
|
||||||
|
|
||||||
for _, d := range domains {
|
for _, d := range domains {
|
||||||
d := strings.ToLower(d)
|
d := strings.ToLower(d)
|
||||||
|
|
||||||
if !domainRegex.MatchString(d) {
|
if !domainRegex.MatchString(d) {
|
||||||
return domainList, fmt.Errorf("invalid domain format: %s", d)
|
return fmt.Errorf("invalid domain format: %s", d)
|
||||||
}
|
}
|
||||||
|
|
||||||
domainList = append(domainList, d)
|
|
||||||
}
|
}
|
||||||
return domainList, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,110 +97,89 @@ func TestValidateDomains(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestValidateDomainsStrSlice tests the ValidateDomainsStrSlice function.
|
func TestValidateDomainsList(t *testing.T) {
|
||||||
func TestValidateDomainsStrSlice(t *testing.T) {
|
|
||||||
// Generate a slice of valid domains up to maxDomains
|
|
||||||
validDomains := make([]string, maxDomains)
|
validDomains := make([]string, maxDomains)
|
||||||
for i := 0; i < maxDomains; i++ {
|
for i := range maxDomains {
|
||||||
validDomains[i] = fmt.Sprintf("example%d.com", i)
|
validDomains[i] = fmt.Sprintf("example%d.com", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
domains []string
|
domains []string
|
||||||
expected []string
|
wantErr bool
|
||||||
wantErr bool
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Empty list",
|
name: "Empty list",
|
||||||
domains: nil,
|
domains: nil,
|
||||||
expected: nil,
|
wantErr: false,
|
||||||
wantErr: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Single valid ASCII domain",
|
name: "Single valid ASCII domain",
|
||||||
domains: []string{"sub.ex-ample.com"},
|
domains: []string{"sub.ex-ample.com"},
|
||||||
expected: []string{"sub.ex-ample.com"},
|
wantErr: false,
|
||||||
wantErr: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Underscores in labels",
|
name: "Underscores in labels",
|
||||||
domains: []string{"_jabber._tcp.gmail.com"},
|
domains: []string{"_jabber._tcp.gmail.com"},
|
||||||
expected: []string{"_jabber._tcp.gmail.com"},
|
wantErr: false,
|
||||||
wantErr: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Unlike ValidateDomains (which converts to punycode),
|
// Unlike ValidateDomains (which converts to punycode),
|
||||||
// ValidateDomainsStrSlice will fail on non-ASCII domain chars.
|
// ValidateDomainsStrSlice will fail on non-ASCII domain chars.
|
||||||
name: "Unicode domain fails (no punycode conversion)",
|
name: "Unicode domain fails (no punycode conversion)",
|
||||||
domains: []string{"münchen.de"},
|
domains: []string{"münchen.de"},
|
||||||
expected: nil,
|
wantErr: true,
|
||||||
wantErr: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Invalid domain format - leading dash",
|
name: "Invalid domain format - leading dash",
|
||||||
domains: []string{"-example.com"},
|
domains: []string{"-example.com"},
|
||||||
expected: nil,
|
wantErr: true,
|
||||||
wantErr: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Invalid domain format - trailing dash",
|
name: "Invalid domain format - trailing dash",
|
||||||
domains: []string{"example-.com"},
|
domains: []string{"example-.com"},
|
||||||
expected: nil,
|
wantErr: true,
|
||||||
wantErr: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// The function stops on the first invalid domain and returns an error,
|
name: "Multiple domains with a valid one, then invalid",
|
||||||
// so only the first domain is definitely valid, but the second is invalid.
|
domains: []string{"google.com", "invalid_domain.com-"},
|
||||||
name: "Multiple domains with a valid one, then invalid",
|
wantErr: true,
|
||||||
domains: []string{"google.com", "invalid_domain.com-"},
|
|
||||||
expected: []string{"google.com"},
|
|
||||||
wantErr: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Valid wildcard domain",
|
name: "Valid wildcard domain",
|
||||||
domains: []string{"*.example.com"},
|
domains: []string{"*.example.com"},
|
||||||
expected: []string{"*.example.com"},
|
wantErr: false,
|
||||||
wantErr: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Wildcard with leading dot - invalid",
|
name: "Wildcard with leading dot - invalid",
|
||||||
domains: []string{".*.example.com"},
|
domains: []string{".*.example.com"},
|
||||||
expected: nil,
|
wantErr: true,
|
||||||
wantErr: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Invalid wildcard with multiple asterisks",
|
name: "Invalid wildcard with multiple asterisks",
|
||||||
domains: []string{"a.*.example.com"},
|
domains: []string{"a.*.example.com"},
|
||||||
expected: nil,
|
wantErr: true,
|
||||||
wantErr: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Exactly maxDomains items (valid)",
|
name: "Exactly maxDomains items (valid)",
|
||||||
domains: validDomains,
|
domains: validDomains,
|
||||||
expected: validDomains,
|
wantErr: false,
|
||||||
wantErr: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Exceeds maxDomains items",
|
name: "Exceeds maxDomains items",
|
||||||
domains: append(validDomains, "extra.com"),
|
domains: append(validDomains, "extra.com"),
|
||||||
expected: nil,
|
wantErr: true,
|
||||||
wantErr: true,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
got, err := ValidateDomainsStrSlice(tt.domains)
|
err := ValidateDomainsList(tt.domains)
|
||||||
// Check if we got an error where expected
|
|
||||||
if tt.wantErr {
|
if tt.wantErr {
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
} else {
|
} else {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare the returned domains to what we expect
|
|
||||||
assert.Equal(t, tt.expected, got)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.26.0
|
// protoc-gen-go v1.26.0
|
||||||
// protoc v3.21.9
|
// protoc v5.29.3
|
||||||
// source: management.proto
|
// source: management.proto
|
||||||
|
|
||||||
package proto
|
package proto
|
||||||
@@ -2194,6 +2194,8 @@ type ProviderConfig struct {
|
|||||||
RedirectURLs []string `protobuf:"bytes,10,rep,name=RedirectURLs,proto3" json:"RedirectURLs,omitempty"`
|
RedirectURLs []string `protobuf:"bytes,10,rep,name=RedirectURLs,proto3" json:"RedirectURLs,omitempty"`
|
||||||
// DisablePromptLogin makes the PKCE flow to not prompt the user for login
|
// DisablePromptLogin makes the PKCE flow to not prompt the user for login
|
||||||
DisablePromptLogin bool `protobuf:"varint,11,opt,name=DisablePromptLogin,proto3" json:"DisablePromptLogin,omitempty"`
|
DisablePromptLogin bool `protobuf:"varint,11,opt,name=DisablePromptLogin,proto3" json:"DisablePromptLogin,omitempty"`
|
||||||
|
// LoginFlags sets the PKCE flow login details
|
||||||
|
LoginFlag uint32 `protobuf:"varint,12,opt,name=LoginFlag,proto3" json:"LoginFlag,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ProviderConfig) Reset() {
|
func (x *ProviderConfig) Reset() {
|
||||||
@@ -2305,6 +2307,13 @@ func (x *ProviderConfig) GetDisablePromptLogin() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *ProviderConfig) GetLoginFlag() uint32 {
|
||||||
|
if x != nil {
|
||||||
|
return x.LoginFlag
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
// Route represents a route.Route object
|
// Route represents a route.Route object
|
||||||
type Route struct {
|
type Route struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
@@ -3596,7 +3605,7 @@ var file_management_proto_rawDesc = []byte{
|
|||||||
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d,
|
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d,
|
||||||
0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64,
|
0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64,
|
||||||
0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64,
|
0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64,
|
||||||
0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x9a, 0x03, 0x0a, 0x0e, 0x50, 0x72, 0x6f,
|
0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xb8, 0x03, 0x0a, 0x0e, 0x50, 0x72, 0x6f,
|
||||||
0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x43,
|
0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x43,
|
||||||
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x43,
|
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x43,
|
||||||
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e,
|
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e,
|
||||||
@@ -3622,180 +3631,181 @@ var file_management_proto_rawDesc = []byte{
|
|||||||
0x74, 0x55, 0x52, 0x4c, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
|
0x74, 0x55, 0x52, 0x4c, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65,
|
||||||
0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28,
|
0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28,
|
||||||
0x08, 0x52, 0x12, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74,
|
0x08, 0x52, 0x12, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74,
|
||||||
0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x22, 0xed, 0x01, 0x0a, 0x05, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12,
|
0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x46, 0x6c,
|
||||||
0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12,
|
0x61, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x46,
|
||||||
0x18, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
0x6c, 0x61, 0x67, 0x22, 0xed, 0x01, 0x0a, 0x05, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x0e, 0x0a,
|
||||||
0x52, 0x07, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x20, 0x0a, 0x0b, 0x4e, 0x65, 0x74,
|
0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x18, 0x0a,
|
||||||
0x77, 0x6f, 0x72, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b,
|
0x07, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
|
||||||
0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x50,
|
0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x20, 0x0a, 0x0b, 0x4e, 0x65, 0x74, 0x77, 0x6f,
|
||||||
0x65, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, 0x65, 0x65, 0x72, 0x12,
|
0x72, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x4e, 0x65,
|
||||||
0x16, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52,
|
0x74, 0x77, 0x6f, 0x72, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x65, 0x65,
|
||||||
0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x61, 0x73, 0x71, 0x75,
|
0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, 0x65, 0x65, 0x72, 0x12, 0x16, 0x0a,
|
||||||
0x65, 0x72, 0x61, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x4d, 0x61, 0x73,
|
0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x4d,
|
||||||
0x71, 0x75, 0x65, 0x72, 0x61, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x4e, 0x65, 0x74, 0x49, 0x44,
|
0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x61, 0x73, 0x71, 0x75, 0x65, 0x72,
|
||||||
0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4e, 0x65, 0x74, 0x49, 0x44, 0x12, 0x18, 0x0a,
|
0x61, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x4d, 0x61, 0x73, 0x71, 0x75,
|
||||||
0x07, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07,
|
0x65, 0x72, 0x61, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x4e, 0x65, 0x74, 0x49, 0x44, 0x18, 0x07,
|
||||||
0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x52,
|
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x4e, 0x65, 0x74, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x44,
|
||||||
0x6f, 0x75, 0x74, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6b, 0x65, 0x65, 0x70,
|
0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x44, 0x6f,
|
||||||
0x52, 0x6f, 0x75, 0x74, 0x65, 0x22, 0xb4, 0x01, 0x0a, 0x09, 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e,
|
0x6d, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x52, 0x6f, 0x75,
|
||||||
0x66, 0x69, 0x67, 0x12, 0x24, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e,
|
0x74, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x52, 0x6f,
|
||||||
0x61, 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x53, 0x65, 0x72, 0x76,
|
0x75, 0x74, 0x65, 0x22, 0xb4, 0x01, 0x0a, 0x09, 0x44, 0x4e, 0x53, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
||||||
0x69, 0x63, 0x65, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x47, 0x0a, 0x10, 0x4e, 0x61, 0x6d,
|
0x67, 0x12, 0x24, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x61, 0x62,
|
||||||
0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x02, 0x20,
|
0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
|
||||||
0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
0x65, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x47, 0x0a, 0x10, 0x4e, 0x61, 0x6d, 0x65, 0x53,
|
||||||
0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70,
|
0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
|
||||||
0x52, 0x10, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75,
|
0x0b, 0x32, 0x1b, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x4e,
|
||||||
0x70, 0x73, 0x12, 0x38, 0x0a, 0x0b, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5a, 0x6f, 0x6e, 0x65,
|
0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x10,
|
||||||
0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
|
0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73,
|
||||||
0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5a, 0x6f, 0x6e, 0x65, 0x52,
|
0x12, 0x38, 0x0a, 0x0b, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5a, 0x6f, 0x6e, 0x65, 0x73, 0x18,
|
||||||
0x0b, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5a, 0x6f, 0x6e, 0x65, 0x73, 0x22, 0x58, 0x0a, 0x0a,
|
0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
|
||||||
0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5a, 0x6f, 0x6e, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x44, 0x6f,
|
0x6e, 0x74, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5a, 0x6f, 0x6e, 0x65, 0x52, 0x0b, 0x43,
|
||||||
0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x44, 0x6f, 0x6d, 0x61,
|
0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5a, 0x6f, 0x6e, 0x65, 0x73, 0x22, 0x58, 0x0a, 0x0a, 0x43, 0x75,
|
||||||
0x69, 0x6e, 0x12, 0x32, 0x0a, 0x07, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x02, 0x20,
|
0x73, 0x74, 0x6f, 0x6d, 0x5a, 0x6f, 0x6e, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x44, 0x6f, 0x6d, 0x61,
|
||||||
0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
|
||||||
0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x07, 0x52,
|
0x12, 0x32, 0x0a, 0x07, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
|
||||||
0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x22, 0x74, 0x0a, 0x0c, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65,
|
0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x53,
|
||||||
0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01,
|
0x69, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x07, 0x52, 0x65, 0x63,
|
||||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79,
|
0x6f, 0x72, 0x64, 0x73, 0x22, 0x74, 0x0a, 0x0c, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65,
|
||||||
0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14,
|
0x63, 0x6f, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||||
0x0a, 0x05, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x43,
|
0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65,
|
||||||
0x6c, 0x61, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x54, 0x54, 0x4c, 0x18, 0x04, 0x20, 0x01, 0x28,
|
0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05,
|
||||||
0x03, 0x52, 0x03, 0x54, 0x54, 0x4c, 0x12, 0x14, 0x0a, 0x05, 0x52, 0x44, 0x61, 0x74, 0x61, 0x18,
|
0x43, 0x6c, 0x61, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x43, 0x6c, 0x61,
|
||||||
0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x52, 0x44, 0x61, 0x74, 0x61, 0x22, 0xb3, 0x01, 0x0a,
|
0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x54, 0x54, 0x4c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||||
0x0f, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70,
|
0x03, 0x54, 0x54, 0x4c, 0x12, 0x14, 0x0a, 0x05, 0x52, 0x44, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20,
|
||||||
0x12, 0x38, 0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18,
|
0x01, 0x28, 0x09, 0x52, 0x05, 0x52, 0x44, 0x61, 0x74, 0x61, 0x22, 0xb3, 0x01, 0x0a, 0x0f, 0x4e,
|
||||||
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
|
0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x38,
|
||||||
0x6e, 0x74, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0b, 0x4e,
|
0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20,
|
||||||
0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x72,
|
0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
||||||
0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x50, 0x72, 0x69,
|
0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0b, 0x4e, 0x61, 0x6d,
|
||||||
0x6d, 0x61, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18,
|
0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x50, 0x72, 0x69, 0x6d,
|
||||||
0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x32,
|
0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x50, 0x72, 0x69, 0x6d, 0x61,
|
||||||
0x0a, 0x14, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x45,
|
0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x03, 0x20,
|
||||||
0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x53, 0x65,
|
0x03, 0x28, 0x09, 0x52, 0x07, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x32, 0x0a, 0x14,
|
||||||
0x61, 0x72, 0x63, 0x68, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c,
|
0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x45, 0x6e, 0x61,
|
||||||
0x65, 0x64, 0x22, 0x48, 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
|
0x62, 0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x53, 0x65, 0x61, 0x72,
|
||||||
0x12, 0x0e, 0x0a, 0x02, 0x49, 0x50, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x50,
|
0x63, 0x68, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64,
|
||||||
0x12, 0x16, 0x0a, 0x06, 0x4e, 0x53, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03,
|
0x22, 0x48, 0x0a, 0x0a, 0x4e, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x0e,
|
||||||
0x52, 0x06, 0x4e, 0x53, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74,
|
0x0a, 0x02, 0x49, 0x50, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x50, 0x12, 0x16,
|
||||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x22, 0xa7, 0x02, 0x0a,
|
0x0a, 0x06, 0x4e, 0x53, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06,
|
||||||
0x0c, 0x46, 0x69, 0x72, 0x65, 0x77, 0x61, 0x6c, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x16, 0x0a,
|
0x4e, 0x53, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x03,
|
||||||
0x06, 0x50, 0x65, 0x65, 0x72, 0x49, 0x50, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x50,
|
0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x22, 0xa7, 0x02, 0x0a, 0x0c, 0x46,
|
||||||
0x65, 0x65, 0x72, 0x49, 0x50, 0x12, 0x37, 0x0a, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69,
|
0x69, 0x72, 0x65, 0x77, 0x61, 0x6c, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x50,
|
||||||
0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67,
|
0x65, 0x65, 0x72, 0x49, 0x50, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x50, 0x65, 0x65,
|
||||||
0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74,
|
0x72, 0x49, 0x50, 0x12, 0x37, 0x0a, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
|
||||||
0x69, 0x6f, 0x6e, 0x52, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e,
|
0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
|
||||||
0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16,
|
0x65, 0x6e, 0x74, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f,
|
||||||
|
0x6e, 0x52, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x06,
|
||||||
|
0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x6d,
|
||||||
|
0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x41, 0x63,
|
||||||
|
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x08,
|
||||||
|
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18,
|
||||||
0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x75, 0x6c, 0x65,
|
0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x75, 0x6c, 0x65,
|
||||||
0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34,
|
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63,
|
||||||
0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e,
|
0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
|
||||||
0x32, 0x18, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x75,
|
0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x30, 0x0a, 0x08, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e,
|
||||||
0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x74,
|
0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67,
|
||||||
0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01,
|
0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08,
|
||||||
0x28, 0x09, 0x52, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x30, 0x0a, 0x08, 0x50, 0x6f, 0x72, 0x74,
|
0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x6f, 0x6c, 0x69,
|
||||||
0x49, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x61, 0x6e,
|
0x63, 0x79, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x50, 0x6f, 0x6c, 0x69,
|
||||||
0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f,
|
0x63, 0x79, 0x49, 0x44, 0x22, 0x38, 0x0a, 0x0e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x41,
|
||||||
0x52, 0x08, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x6f,
|
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x65, 0x74, 0x49, 0x50, 0x18,
|
||||||
0x6c, 0x69, 0x63, 0x79, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x50, 0x6f,
|
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x65, 0x74, 0x49, 0x50, 0x12, 0x10, 0x0a, 0x03,
|
||||||
0x6c, 0x69, 0x63, 0x79, 0x49, 0x44, 0x22, 0x38, 0x0a, 0x0e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72,
|
0x6d, 0x61, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x61, 0x63, 0x22, 0x1e,
|
||||||
0x6b, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x65, 0x74, 0x49,
|
0x0a, 0x06, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x46, 0x69, 0x6c, 0x65,
|
||||||
0x50, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x65, 0x74, 0x49, 0x50, 0x12, 0x10,
|
0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x96,
|
||||||
0x0a, 0x03, 0x6d, 0x61, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x61, 0x63,
|
0x01, 0x0a, 0x08, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x04, 0x70,
|
||||||
0x22, 0x1e, 0x0a, 0x06, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x46, 0x69,
|
0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x04, 0x70, 0x6f, 0x72,
|
||||||
0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x46, 0x69, 0x6c, 0x65, 0x73,
|
0x74, 0x12, 0x32, 0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
|
||||||
0x22, 0x96, 0x01, 0x0a, 0x08, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a,
|
0x32, 0x1a, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x6f,
|
||||||
0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x04, 0x70,
|
0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x48, 0x00, 0x52, 0x05,
|
||||||
0x6f, 0x72, 0x74, 0x12, 0x32, 0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01,
|
0x72, 0x61, 0x6e, 0x67, 0x65, 0x1a, 0x2f, 0x0a, 0x05, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x14,
|
||||||
0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
|
0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x73,
|
||||||
0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x48, 0x00,
|
0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||||
0x52, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x1a, 0x2f, 0x0a, 0x05, 0x52, 0x61, 0x6e, 0x67, 0x65,
|
0x0d, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x42, 0x0f, 0x0a, 0x0d, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x65,
|
||||||
0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52,
|
0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x87, 0x03, 0x0a, 0x11, 0x52, 0x6f, 0x75, 0x74,
|
||||||
0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20,
|
0x65, 0x46, 0x69, 0x72, 0x65, 0x77, 0x61, 0x6c, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x22, 0x0a,
|
||||||
0x01, 0x28, 0x0d, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x42, 0x0f, 0x0a, 0x0d, 0x70, 0x6f, 0x72, 0x74,
|
0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20,
|
||||||
0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x87, 0x03, 0x0a, 0x11, 0x52, 0x6f,
|
0x03, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65,
|
||||||
0x75, 0x74, 0x65, 0x46, 0x69, 0x72, 0x65, 0x77, 0x61, 0x6c, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x12,
|
0x73, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||||
0x22, 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18,
|
0x0e, 0x32, 0x16, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x52,
|
||||||
0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x61, 0x6e,
|
0x75, 0x6c, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f,
|
||||||
0x67, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20,
|
0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||||
0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74,
|
||||||
0x2e, 0x52, 0x75, 0x6c, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74,
|
0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18,
|
||||||
0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69,
|
0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
|
||||||
0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e,
|
0x6e, 0x74, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52,
|
||||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f,
|
0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x30, 0x0a, 0x08, 0x70, 0x6f, 0x72,
|
||||||
0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
|
0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x61,
|
||||||
0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f,
|
0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66,
|
||||||
0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x30, 0x0a, 0x08, 0x70,
|
0x6f, 0x52, 0x08, 0x70, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x69,
|
||||||
0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e,
|
0x73, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09,
|
||||||
0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x49,
|
0x69, 0x73, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x6f, 0x6d,
|
||||||
0x6e, 0x66, 0x6f, 0x52, 0x08, 0x70, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a,
|
0x61, 0x69, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x64, 0x6f, 0x6d, 0x61,
|
||||||
0x09, 0x69, 0x73, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08,
|
0x69, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x50, 0x72, 0x6f,
|
||||||
0x52, 0x09, 0x69, 0x73, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x64,
|
0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x63, 0x75, 0x73,
|
||||||
0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x64, 0x6f,
|
0x74, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x50,
|
||||||
0x6d, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x50,
|
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x49, 0x44, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x50,
|
||||||
0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x63,
|
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x52, 0x6f, 0x75, 0x74, 0x65,
|
||||||
0x75, 0x73, 0x74, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x1a, 0x0a,
|
0x49, 0x44, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x49,
|
||||||
0x08, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x49, 0x44, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
0x44, 0x22, 0xf2, 0x01, 0x0a, 0x0e, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67,
|
||||||
0x08, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x52, 0x6f, 0x75,
|
0x52, 0x75, 0x6c, 0x65, 0x12, 0x34, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
|
||||||
0x74, 0x65, 0x49, 0x44, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x52, 0x6f, 0x75, 0x74,
|
0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
|
||||||
0x65, 0x49, 0x44, 0x22, 0xf2, 0x01, 0x0a, 0x0e, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69,
|
0x65, 0x6e, 0x74, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
|
||||||
0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x34, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63,
|
0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x3e, 0x0a, 0x0f, 0x64, 0x65,
|
||||||
0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67,
|
0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20,
|
||||||
0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63,
|
0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
||||||
0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x3e, 0x0a, 0x0f,
|
0x2e, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x69,
|
||||||
0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x18,
|
0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x11, 0x74, 0x72,
|
||||||
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
|
0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18,
|
||||||
0x6e, 0x74, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x64, 0x65, 0x73,
|
0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65,
|
||||||
0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x11,
|
0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3c, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e,
|
||||||
0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73,
|
0x73, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b,
|
||||||
0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61,
|
0x32, 0x14, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x6f,
|
||||||
0x74, 0x65, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3c, 0x0a, 0x0e, 0x74, 0x72,
|
0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74,
|
||||||
0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01,
|
0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x2a, 0x4c, 0x0a, 0x0c, 0x52, 0x75, 0x6c, 0x65, 0x50, 0x72,
|
||||||
0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
|
0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57,
|
||||||
0x50, 0x6f, 0x72, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c,
|
0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4c, 0x4c, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03,
|
||||||
0x61, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x2a, 0x4c, 0x0a, 0x0c, 0x52, 0x75, 0x6c, 0x65,
|
0x54, 0x43, 0x50, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x44, 0x50, 0x10, 0x03, 0x12, 0x08,
|
||||||
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e,
|
0x0a, 0x04, 0x49, 0x43, 0x4d, 0x50, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x55, 0x53, 0x54,
|
||||||
0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4c, 0x4c, 0x10, 0x01, 0x12, 0x07,
|
0x4f, 0x4d, 0x10, 0x05, 0x2a, 0x20, 0x0a, 0x0d, 0x52, 0x75, 0x6c, 0x65, 0x44, 0x69, 0x72, 0x65,
|
||||||
0x0a, 0x03, 0x54, 0x43, 0x50, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x44, 0x50, 0x10, 0x03,
|
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x06, 0x0a, 0x02, 0x49, 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a,
|
||||||
0x12, 0x08, 0x0a, 0x04, 0x49, 0x43, 0x4d, 0x50, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x55,
|
0x03, 0x4f, 0x55, 0x54, 0x10, 0x01, 0x2a, 0x22, 0x0a, 0x0a, 0x52, 0x75, 0x6c, 0x65, 0x41, 0x63,
|
||||||
0x53, 0x54, 0x4f, 0x4d, 0x10, 0x05, 0x2a, 0x20, 0x0a, 0x0d, 0x52, 0x75, 0x6c, 0x65, 0x44, 0x69,
|
0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x10, 0x00,
|
||||||
0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x06, 0x0a, 0x02, 0x49, 0x4e, 0x10, 0x00, 0x12,
|
0x12, 0x08, 0x0a, 0x04, 0x44, 0x52, 0x4f, 0x50, 0x10, 0x01, 0x32, 0x90, 0x04, 0x0a, 0x11, 0x4d,
|
||||||
0x07, 0x0a, 0x03, 0x4f, 0x55, 0x54, 0x10, 0x01, 0x2a, 0x22, 0x0a, 0x0a, 0x52, 0x75, 0x6c, 0x65,
|
0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||||
0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54,
|
0x12, 0x45, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61,
|
||||||
0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x52, 0x4f, 0x50, 0x10, 0x01, 0x32, 0x90, 0x04, 0x0a,
|
|
||||||
0x11, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69,
|
|
||||||
0x63, 0x65, 0x12, 0x45, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x1c, 0x2e, 0x6d, 0x61,
|
|
||||||
0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74,
|
|
||||||
0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61,
|
|
||||||
0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64,
|
0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64,
|
||||||
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x04, 0x53, 0x79, 0x6e,
|
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
|
||||||
0x63, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45,
|
0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65,
|
||||||
0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a,
|
0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x04, 0x53, 0x79, 0x6e, 0x63, 0x12,
|
||||||
0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63,
|
0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63,
|
||||||
0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30,
|
0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e,
|
||||||
0x01, 0x12, 0x42, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65,
|
0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79,
|
||||||
0x79, 0x12, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45,
|
0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12,
|
||||||
0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
|
0x42, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12,
|
||||||
0x74, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70,
|
||||||
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x33, 0x0a, 0x09, 0x69, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74,
|
0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
|
||||||
0x68, 0x79, 0x12, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
|
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||||
0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
|
0x65, 0x22, 0x00, 0x12, 0x33, 0x0a, 0x09, 0x69, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79,
|
||||||
0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x1a, 0x47, 0x65,
|
0x12, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d,
|
||||||
0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61,
|
0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
||||||
0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6c, 0x6f, 0x77, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67,
|
0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x44,
|
||||||
0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d,
|
0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69,
|
||||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
|
0x6f, 0x6e, 0x46, 0x6c, 0x6f, 0x77, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
|
||||||
0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73,
|
0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73,
|
||||||
0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x50, 0x4b, 0x43,
|
0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
|
||||||
0x45, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6c,
|
0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61,
|
||||||
0x6f, 0x77, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
|
0x67, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x50, 0x4b, 0x43, 0x45, 0x41,
|
||||||
0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6c, 0x6f, 0x77,
|
||||||
0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e,
|
0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e,
|
||||||
0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00,
|
0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c,
|
||||||
0x12, 0x3d, 0x0a, 0x08, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x1c, 0x2e, 0x6d,
|
0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72,
|
||||||
0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70,
|
0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x3d,
|
||||||
0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x6e,
|
0x0a, 0x08, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e,
|
||||||
0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42,
|
0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65,
|
||||||
0x08, 0x5a, 0x06, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67,
|
||||||
0x33,
|
0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x08, 0x5a,
|
||||||
|
0x06, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -374,6 +374,8 @@ message ProviderConfig {
|
|||||||
repeated string RedirectURLs = 10;
|
repeated string RedirectURLs = 10;
|
||||||
// DisablePromptLogin makes the PKCE flow to not prompt the user for login
|
// DisablePromptLogin makes the PKCE flow to not prompt the user for login
|
||||||
bool DisablePromptLogin = 11;
|
bool DisablePromptLogin = 11;
|
||||||
|
// LoginFlags sets the PKCE flow login details
|
||||||
|
uint32 LoginFlag = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Route represents a route.Route object
|
// Route represents a route.Route object
|
||||||
|
|||||||
@@ -196,21 +196,7 @@ func BuildManager(
|
|||||||
permissionsManager: permissionsManager,
|
permissionsManager: permissionsManager,
|
||||||
}
|
}
|
||||||
|
|
||||||
var initialInterval int64
|
am.startWarmup(ctx)
|
||||||
intervalStr := os.Getenv("PEER_UPDATE_INTERVAL_MS")
|
|
||||||
interval, err := strconv.Atoi(intervalStr)
|
|
||||||
if err != nil {
|
|
||||||
initialInterval = 1
|
|
||||||
} else {
|
|
||||||
initialInterval = int64(interval) * 10
|
|
||||||
go func() {
|
|
||||||
time.Sleep(30 * time.Second)
|
|
||||||
am.updateAccountPeersBufferInterval.Store(int64(time.Duration(interval) * time.Millisecond))
|
|
||||||
log.WithContext(ctx).Infof("set peer update buffer interval to %dms", interval)
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
am.updateAccountPeersBufferInterval.Store(initialInterval)
|
|
||||||
log.WithContext(ctx).Infof("set peer update buffer interval to %dms", initialInterval)
|
|
||||||
|
|
||||||
accountsCounter, err := store.GetAccountsCounter(ctx)
|
accountsCounter, err := store.GetAccountsCounter(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -254,6 +240,32 @@ func BuildManager(
|
|||||||
return am, nil
|
return am, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (am *DefaultAccountManager) startWarmup(ctx context.Context) {
|
||||||
|
var initialInterval int64
|
||||||
|
intervalStr := os.Getenv("NB_PEER_UPDATE_INTERVAL_MS")
|
||||||
|
interval, err := strconv.Atoi(intervalStr)
|
||||||
|
if err != nil {
|
||||||
|
initialInterval = 1
|
||||||
|
log.WithContext(ctx).Warnf("failed to parse peer update interval, using default value %dms: %v", initialInterval, err)
|
||||||
|
} else {
|
||||||
|
initialInterval = int64(interval) * 10
|
||||||
|
go func() {
|
||||||
|
startupPeriodStr := os.Getenv("NB_PEER_UPDATE_STARTUP_PERIOD_S")
|
||||||
|
startupPeriod, err := strconv.Atoi(startupPeriodStr)
|
||||||
|
if err != nil {
|
||||||
|
startupPeriod = 1
|
||||||
|
log.WithContext(ctx).Warnf("failed to parse peer update startup period, using default value %ds: %v", startupPeriod, err)
|
||||||
|
}
|
||||||
|
time.Sleep(time.Duration(startupPeriod) * time.Second)
|
||||||
|
am.updateAccountPeersBufferInterval.Store(int64(time.Duration(interval) * time.Millisecond))
|
||||||
|
log.WithContext(ctx).Infof("set peer update buffer interval to %dms", interval)
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
am.updateAccountPeersBufferInterval.Store(initialInterval)
|
||||||
|
log.WithContext(ctx).Infof("set peer update buffer interval to %dms", initialInterval)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (am *DefaultAccountManager) GetExternalCacheManager() account.ExternalCacheManager {
|
func (am *DefaultAccountManager) GetExternalCacheManager() account.ExternalCacheManager {
|
||||||
return am.externalCacheManager
|
return am.externalCacheManager
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -847,6 +847,7 @@ func (s *GRPCServer) GetPKCEAuthorizationFlow(ctx context.Context, req *proto.En
|
|||||||
RedirectURLs: s.config.PKCEAuthorizationFlow.ProviderConfig.RedirectURLs,
|
RedirectURLs: s.config.PKCEAuthorizationFlow.ProviderConfig.RedirectURLs,
|
||||||
UseIDToken: s.config.PKCEAuthorizationFlow.ProviderConfig.UseIDToken,
|
UseIDToken: s.config.PKCEAuthorizationFlow.ProviderConfig.UseIDToken,
|
||||||
DisablePromptLogin: s.config.PKCEAuthorizationFlow.ProviderConfig.DisablePromptLogin,
|
DisablePromptLogin: s.config.PKCEAuthorizationFlow.ProviderConfig.DisablePromptLogin,
|
||||||
|
LoginFlag: uint32(s.config.PKCEAuthorizationFlow.ProviderConfig.LoginFlag),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4308,6 +4308,13 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
enum: [TYPE_UNKNOWN, TYPE_START, TYPE_END, TYPE_DROP]
|
enum: [TYPE_UNKNOWN, TYPE_START, TYPE_END, TYPE_DROP]
|
||||||
|
- name: connection_type
|
||||||
|
in: query
|
||||||
|
description: Filter by connection type
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum: [P2P, ROUTED]
|
||||||
- name: direction
|
- name: direction
|
||||||
in: query
|
in: query
|
||||||
description: Filter by direction
|
description: Filter by direction
|
||||||
|
|||||||
@@ -186,6 +186,12 @@ const (
|
|||||||
GetApiEventsNetworkTrafficParamsTypeTYPEUNKNOWN GetApiEventsNetworkTrafficParamsType = "TYPE_UNKNOWN"
|
GetApiEventsNetworkTrafficParamsTypeTYPEUNKNOWN GetApiEventsNetworkTrafficParamsType = "TYPE_UNKNOWN"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Defines values for GetApiEventsNetworkTrafficParamsConnectionType.
|
||||||
|
const (
|
||||||
|
GetApiEventsNetworkTrafficParamsConnectionTypeP2P GetApiEventsNetworkTrafficParamsConnectionType = "P2P"
|
||||||
|
GetApiEventsNetworkTrafficParamsConnectionTypeROUTED GetApiEventsNetworkTrafficParamsConnectionType = "ROUTED"
|
||||||
|
)
|
||||||
|
|
||||||
// Defines values for GetApiEventsNetworkTrafficParamsDirection.
|
// Defines values for GetApiEventsNetworkTrafficParamsDirection.
|
||||||
const (
|
const (
|
||||||
GetApiEventsNetworkTrafficParamsDirectionDIRECTIONUNKNOWN GetApiEventsNetworkTrafficParamsDirection = "DIRECTION_UNKNOWN"
|
GetApiEventsNetworkTrafficParamsDirectionDIRECTIONUNKNOWN GetApiEventsNetworkTrafficParamsDirection = "DIRECTION_UNKNOWN"
|
||||||
@@ -1784,6 +1790,9 @@ type GetApiEventsNetworkTrafficParams struct {
|
|||||||
// Type Filter by event type
|
// Type Filter by event type
|
||||||
Type *GetApiEventsNetworkTrafficParamsType `form:"type,omitempty" json:"type,omitempty"`
|
Type *GetApiEventsNetworkTrafficParamsType `form:"type,omitempty" json:"type,omitempty"`
|
||||||
|
|
||||||
|
// ConnectionType Filter by connection type
|
||||||
|
ConnectionType *GetApiEventsNetworkTrafficParamsConnectionType `form:"connection_type,omitempty" json:"connection_type,omitempty"`
|
||||||
|
|
||||||
// Direction Filter by direction
|
// Direction Filter by direction
|
||||||
Direction *GetApiEventsNetworkTrafficParamsDirection `form:"direction,omitempty" json:"direction,omitempty"`
|
Direction *GetApiEventsNetworkTrafficParamsDirection `form:"direction,omitempty" json:"direction,omitempty"`
|
||||||
|
|
||||||
@@ -1800,6 +1809,9 @@ type GetApiEventsNetworkTrafficParams struct {
|
|||||||
// GetApiEventsNetworkTrafficParamsType defines parameters for GetApiEventsNetworkTraffic.
|
// GetApiEventsNetworkTrafficParamsType defines parameters for GetApiEventsNetworkTraffic.
|
||||||
type GetApiEventsNetworkTrafficParamsType string
|
type GetApiEventsNetworkTrafficParamsType string
|
||||||
|
|
||||||
|
// GetApiEventsNetworkTrafficParamsConnectionType defines parameters for GetApiEventsNetworkTraffic.
|
||||||
|
type GetApiEventsNetworkTrafficParamsConnectionType string
|
||||||
|
|
||||||
// GetApiEventsNetworkTrafficParamsDirection defines parameters for GetApiEventsNetworkTraffic.
|
// GetApiEventsNetworkTrafficParamsDirection defines parameters for GetApiEventsNetworkTraffic.
|
||||||
type GetApiEventsNetworkTrafficParamsDirection string
|
type GetApiEventsNetworkTrafficParamsDirection string
|
||||||
|
|
||||||
|
|||||||
@@ -556,6 +556,10 @@ func (am *DefaultAccountManager) AddPeer(ctx context.Context, setupKey, userID s
|
|||||||
return fmt.Errorf("failed to get free IP: %w", err)
|
return fmt.Errorf("failed to get free IP: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := domain.ValidateDomainsList(peer.ExtraDNSLabels); err != nil {
|
||||||
|
return status.Errorf(status.InvalidArgument, "invalid extra DNS labels: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
registrationTime := time.Now().UTC()
|
registrationTime := time.Now().UTC()
|
||||||
newPeer = &nbpeer.Peer{
|
newPeer = &nbpeer.Peer{
|
||||||
ID: xid.New().String(),
|
ID: xid.New().String(),
|
||||||
@@ -767,10 +771,11 @@ func (am *DefaultAccountManager) handlePeerLoginNotFound(ctx context.Context, lo
|
|||||||
// we couldn't find this peer by its public key which can mean that peer hasn't been registered yet.
|
// we couldn't find this peer by its public key which can mean that peer hasn't been registered yet.
|
||||||
// Try registering it.
|
// Try registering it.
|
||||||
newPeer := &nbpeer.Peer{
|
newPeer := &nbpeer.Peer{
|
||||||
Key: login.WireGuardPubKey,
|
Key: login.WireGuardPubKey,
|
||||||
Meta: login.Meta,
|
Meta: login.Meta,
|
||||||
SSHKey: login.SSHKey,
|
SSHKey: login.SSHKey,
|
||||||
Location: nbpeer.Location{ConnectionIP: login.ConnectionIP},
|
Location: nbpeer.Location{ConnectionIP: login.ConnectionIP},
|
||||||
|
ExtraDNSLabels: login.ExtraDNSLabels,
|
||||||
}
|
}
|
||||||
|
|
||||||
return am.AddPeer(ctx, login.SetupKey, login.UserID, newPeer)
|
return am.AddPeer(ctx, login.SetupKey, login.UserID, newPeer)
|
||||||
@@ -875,16 +880,6 @@ func (am *DefaultAccountManager) LoginPeer(ctx context.Context, login types.Peer
|
|||||||
return status.Errorf(status.PreconditionFailed, "couldn't login peer: setup key doesn't allow extra DNS labels")
|
return status.Errorf(status.PreconditionFailed, "couldn't login peer: setup key doesn't allow extra DNS labels")
|
||||||
}
|
}
|
||||||
|
|
||||||
extraLabels, err := domain.ValidateDomainsStrSlice(login.ExtraDNSLabels)
|
|
||||||
if err != nil {
|
|
||||||
return status.Errorf(status.InvalidArgument, "invalid extra DNS labels: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !slices.Equal(peer.ExtraDNSLabels, extraLabels) {
|
|
||||||
peer.ExtraDNSLabels = extraLabels
|
|
||||||
shouldStorePeer = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if shouldStorePeer {
|
if shouldStorePeer {
|
||||||
if err = transaction.SavePeer(ctx, store.LockingStrengthUpdate, accountID, peer); err != nil {
|
if err = transaction.SavePeer(ctx, store.LockingStrengthUpdate, accountID, peer); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"net/netip"
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -1290,15 +1291,21 @@ func Test_RegisterPeerByUser(t *testing.T) {
|
|||||||
Status: &nbpeer.PeerStatus{Connected: false, LastSeen: time.Now()},
|
Status: &nbpeer.PeerStatus{Connected: false, LastSeen: time.Now()},
|
||||||
SSHEnabled: false,
|
SSHEnabled: false,
|
||||||
LastLogin: util.ToPtr(time.Now()),
|
LastLogin: util.ToPtr(time.Now()),
|
||||||
|
ExtraDNSLabels: []string{
|
||||||
|
"extraLabel1",
|
||||||
|
"extraLabel2",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
addedPeer, _, _, err := am.AddPeer(context.Background(), "", existingUserID, newPeer)
|
addedPeer, _, _, err := am.AddPeer(context.Background(), "", existingUserID, newPeer)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, newPeer.ExtraDNSLabels, addedPeer.ExtraDNSLabels)
|
||||||
|
|
||||||
peer, err := s.GetPeerByPeerPubKey(context.Background(), store.LockingStrengthShare, addedPeer.Key)
|
peer, err := s.GetPeerByPeerPubKey(context.Background(), store.LockingStrengthShare, addedPeer.Key)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, peer.AccountID, existingAccountID)
|
assert.Equal(t, peer.AccountID, existingAccountID)
|
||||||
assert.Equal(t, peer.UserID, existingUserID)
|
assert.Equal(t, peer.UserID, existingUserID)
|
||||||
|
assert.Equal(t, newPeer.ExtraDNSLabels, peer.ExtraDNSLabels)
|
||||||
|
|
||||||
account, err := s.GetAccount(context.Background(), existingAccountID)
|
account, err := s.GetAccount(context.Background(), existingAccountID)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -1339,15 +1346,12 @@ func Test_RegisterPeerBySetupKey(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
existingAccountID := "bf1c8084-ba50-4ce7-9439-34653001fc3b"
|
existingAccountID := "bf1c8084-ba50-4ce7-9439-34653001fc3b"
|
||||||
existingSetupKeyID := "A2C8E62B-38F5-4553-B31E-DD66C696CEBB"
|
|
||||||
|
|
||||||
_, err = s.GetAccount(context.Background(), existingAccountID)
|
_, err = s.GetAccount(context.Background(), existingAccountID)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
newPeer := &nbpeer.Peer{
|
newPeerTemplate := &nbpeer.Peer{
|
||||||
ID: xid.New().String(),
|
|
||||||
AccountID: existingAccountID,
|
AccountID: existingAccountID,
|
||||||
Key: "newPeerKey",
|
|
||||||
UserID: "",
|
UserID: "",
|
||||||
IP: net.IP{123, 123, 123, 123},
|
IP: net.IP{123, 123, 123, 123},
|
||||||
Meta: nbpeer.PeerSystemMeta{
|
Meta: nbpeer.PeerSystemMeta{
|
||||||
@@ -1358,31 +1362,96 @@ func Test_RegisterPeerBySetupKey(t *testing.T) {
|
|||||||
DNSLabel: "newPeer.test",
|
DNSLabel: "newPeer.test",
|
||||||
Status: &nbpeer.PeerStatus{Connected: false, LastSeen: time.Now()},
|
Status: &nbpeer.PeerStatus{Connected: false, LastSeen: time.Now()},
|
||||||
SSHEnabled: false,
|
SSHEnabled: false,
|
||||||
|
ExtraDNSLabels: []string{
|
||||||
|
"extraLabel1",
|
||||||
|
"extraLabel2",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
addedPeer, _, _, err := am.AddPeer(context.Background(), existingSetupKeyID, "", newPeer)
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
existingSetupKeyID string
|
||||||
|
expectedGroupIDsInAccount []string
|
||||||
|
expectAddPeerError bool
|
||||||
|
expectedErrorMsgSubstring string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Successful registration with setup key allowing extra DNS labels",
|
||||||
|
existingSetupKeyID: "A2C8E62B-38F5-4553-B31E-DD66C696CEBD",
|
||||||
|
expectAddPeerError: false,
|
||||||
|
expectedGroupIDsInAccount: []string{"cfefqs706sqkneg59g2g", "cfefqs706sqkneg59g4g"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Failed registration with setup key not allowing extra DNS labels",
|
||||||
|
existingSetupKeyID: "A2C8E62B-38F5-4553-B31E-DD66C696CEBB",
|
||||||
|
expectAddPeerError: true,
|
||||||
|
expectedErrorMsgSubstring: "setup key doesn't allow extra DNS labels",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Absent setup key",
|
||||||
|
existingSetupKeyID: "AAAAAAAA-38F5-4553-B31E-DD66C696CEBB",
|
||||||
|
expectAddPeerError: true,
|
||||||
|
expectedErrorMsgSubstring: "failed adding new peer: account not found",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
require.NoError(t, err)
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
currentPeer := &nbpeer.Peer{
|
||||||
|
ID: xid.New().String(),
|
||||||
|
AccountID: newPeerTemplate.AccountID,
|
||||||
|
Key: "newPeerKey_" + xid.New().String(),
|
||||||
|
UserID: newPeerTemplate.UserID,
|
||||||
|
IP: newPeerTemplate.IP,
|
||||||
|
Meta: newPeerTemplate.Meta,
|
||||||
|
Name: newPeerTemplate.Name,
|
||||||
|
DNSLabel: newPeerTemplate.DNSLabel,
|
||||||
|
Status: &nbpeer.PeerStatus{Connected: false, LastSeen: time.Now()},
|
||||||
|
SSHEnabled: newPeerTemplate.SSHEnabled,
|
||||||
|
ExtraDNSLabels: newPeerTemplate.ExtraDNSLabels,
|
||||||
|
}
|
||||||
|
|
||||||
peer, err := s.GetPeerByPeerPubKey(context.Background(), store.LockingStrengthShare, newPeer.Key)
|
addedPeer, _, _, err := am.AddPeer(context.Background(), tc.existingSetupKeyID, "", currentPeer)
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, peer.AccountID, existingAccountID)
|
|
||||||
|
|
||||||
account, err := s.GetAccount(context.Background(), existingAccountID)
|
if tc.expectAddPeerError {
|
||||||
require.NoError(t, err)
|
require.Error(t, err, "Expected an error when adding peer with setup key: %s", tc.existingSetupKeyID)
|
||||||
assert.Contains(t, account.Peers, addedPeer.ID)
|
assert.Contains(t, err.Error(), tc.expectedErrorMsgSubstring, "Error message mismatch")
|
||||||
assert.Contains(t, account.Groups["cfefqs706sqkneg59g2g"].Peers, addedPeer.ID)
|
return
|
||||||
assert.Contains(t, account.Groups["cfefqs706sqkneg59g4g"].Peers, addedPeer.ID)
|
}
|
||||||
|
|
||||||
assert.Equal(t, uint64(1), account.Network.Serial)
|
require.NoError(t, err, "Expected no error when adding peer with setup key: %s", tc.existingSetupKeyID)
|
||||||
|
assert.NotNil(t, addedPeer, "addedPeer should not be nil on success")
|
||||||
|
assert.Equal(t, currentPeer.ExtraDNSLabels, addedPeer.ExtraDNSLabels, "ExtraDNSLabels mismatch")
|
||||||
|
|
||||||
lastUsed, err := time.Parse("2006-01-02T15:04:05Z", "0001-01-01T00:00:00Z")
|
peerFromStore, err := s.GetPeerByPeerPubKey(context.Background(), store.LockingStrengthShare, currentPeer.Key)
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err, "Failed to get peer by pub key: %s", currentPeer.Key)
|
||||||
|
assert.Equal(t, existingAccountID, peerFromStore.AccountID, "AccountID mismatch for peer from store")
|
||||||
|
assert.Equal(t, currentPeer.ExtraDNSLabels, peerFromStore.ExtraDNSLabels, "ExtraDNSLabels mismatch for peer from store")
|
||||||
|
assert.Equal(t, addedPeer.ID, peerFromStore.ID, "Peer ID mismatch between addedPeer and peerFromStore")
|
||||||
|
|
||||||
hashedKey := sha256.Sum256([]byte(existingSetupKeyID))
|
account, err := s.GetAccount(context.Background(), existingAccountID)
|
||||||
encodedHashedKey := b64.StdEncoding.EncodeToString(hashedKey[:])
|
require.NoError(t, err, "Failed to get account: %s", existingAccountID)
|
||||||
assert.NotEqual(t, lastUsed, account.SetupKeys[encodedHashedKey].LastUsed)
|
assert.Contains(t, account.Peers, addedPeer.ID, "Peer ID not found in account.Peers")
|
||||||
assert.Equal(t, 1, account.SetupKeys[encodedHashedKey].UsedTimes)
|
|
||||||
|
for _, groupID := range tc.expectedGroupIDsInAccount {
|
||||||
|
require.NotNil(t, account.Groups[groupID], "Group %s not found in account", groupID)
|
||||||
|
assert.Contains(t, account.Groups[groupID].Peers, addedPeer.ID, "Peer ID %s not found in group %s", addedPeer.ID, groupID)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, uint64(1), account.Network.Serial, "Network.Serial mismatch; this assumes specific initial state or increment logic.")
|
||||||
|
|
||||||
|
hashedKey := sha256.Sum256([]byte(tc.existingSetupKeyID))
|
||||||
|
encodedHashedKey := b64.StdEncoding.EncodeToString(hashedKey[:])
|
||||||
|
|
||||||
|
setupKeyData, ok := account.SetupKeys[encodedHashedKey]
|
||||||
|
require.True(t, ok, "Setup key data not found in account.SetupKeys for key ID %s (encoded: %s)", tc.existingSetupKeyID, encodedHashedKey)
|
||||||
|
|
||||||
|
var zeroTime time.Time
|
||||||
|
assert.NotEqual(t, zeroTime, setupKeyData.LastUsed, "Setup key LastUsed time should have been updated and not be zero.")
|
||||||
|
|
||||||
|
assert.Equal(t, 1, setupKeyData.UsedTimes, "Setup key UsedTimes should be 1 after first use.")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1456,6 +1525,160 @@ func Test_RegisterPeerRollbackOnFailure(t *testing.T) {
|
|||||||
assert.Equal(t, 0, account.SetupKeys[encodedHashedKey].UsedTimes)
|
assert.Equal(t, 0, account.SetupKeys[encodedHashedKey].UsedTimes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_LoginPeer(t *testing.T) {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
t.Skip("The SQLite store is not properly supported by Windows yet")
|
||||||
|
}
|
||||||
|
|
||||||
|
s, cleanup, err := store.NewTestStoreFromSQL(context.Background(), "testdata/extended-store.sql", t.TempDir())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer cleanup()
|
||||||
|
|
||||||
|
eventStore := &activity.InMemoryEventStore{}
|
||||||
|
|
||||||
|
metrics, err := telemetry.NewDefaultAppMetrics(context.Background())
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
|
t.Cleanup(ctrl.Finish)
|
||||||
|
settingsMockManager := settings.NewMockManager(ctrl)
|
||||||
|
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)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
existingAccountID := "bf1c8084-ba50-4ce7-9439-34653001fc3b"
|
||||||
|
_, err = s.GetAccount(context.Background(), existingAccountID)
|
||||||
|
require.NoError(t, err, "Failed to get existing account, check testdata/extended-store.sql. Account ID: %s", existingAccountID)
|
||||||
|
|
||||||
|
baseMeta := nbpeer.PeerSystemMeta{
|
||||||
|
Hostname: "loginPeerHost",
|
||||||
|
GoOS: "linux",
|
||||||
|
}
|
||||||
|
|
||||||
|
newPeerTemplate := &nbpeer.Peer{
|
||||||
|
AccountID: existingAccountID,
|
||||||
|
UserID: "",
|
||||||
|
IP: net.IP{123, 123, 123, 123},
|
||||||
|
Meta: nbpeer.PeerSystemMeta{
|
||||||
|
Hostname: "newPeer",
|
||||||
|
GoOS: "linux",
|
||||||
|
},
|
||||||
|
Name: "newPeerName",
|
||||||
|
DNSLabel: "newPeer.test",
|
||||||
|
Status: &nbpeer.PeerStatus{Connected: false, LastSeen: time.Now()},
|
||||||
|
SSHEnabled: false,
|
||||||
|
ExtraDNSLabels: []string{
|
||||||
|
"extraLabel1",
|
||||||
|
"extraLabel2",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
setupKey string
|
||||||
|
wireGuardPubKey string
|
||||||
|
expectExtraDNSLabelsMismatch bool
|
||||||
|
extraDNSLabels []string
|
||||||
|
expectLoginError bool
|
||||||
|
expectedErrorMsgSubstring string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Successful login with setup key",
|
||||||
|
setupKey: "A2C8E62B-38F5-4553-B31E-DD66C696CEBD",
|
||||||
|
expectLoginError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Successful login with setup key with DNS labels mismatch",
|
||||||
|
setupKey: "A2C8E62B-38F5-4553-B31E-DD66C696CEBD",
|
||||||
|
expectExtraDNSLabelsMismatch: true,
|
||||||
|
extraDNSLabels: []string{"anotherLabel1", "anotherLabel2"},
|
||||||
|
expectLoginError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Failed login with setup key not allowing extra DNS labels",
|
||||||
|
setupKey: "A2C8E62B-38F5-4553-B31E-DD66C696CEBB",
|
||||||
|
expectExtraDNSLabelsMismatch: true,
|
||||||
|
extraDNSLabels: []string{"anotherLabel1", "anotherLabel2"},
|
||||||
|
expectLoginError: true,
|
||||||
|
expectedErrorMsgSubstring: "setup key doesn't allow extra DNS labels",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
currentWireGuardPubKey := "testPubKey_" + xid.New().String()
|
||||||
|
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
upperKey := strings.ToUpper(tc.setupKey)
|
||||||
|
hashedKey := sha256.Sum256([]byte(upperKey))
|
||||||
|
encodedHashedKey := b64.StdEncoding.EncodeToString(hashedKey[:])
|
||||||
|
sk, err := s.GetSetupKeyBySecret(context.Background(), store.LockingStrengthUpdate, encodedHashedKey)
|
||||||
|
require.NoError(t, err, "Failed to get setup key %s from storage", tc.setupKey)
|
||||||
|
|
||||||
|
currentPeer := &nbpeer.Peer{
|
||||||
|
ID: xid.New().String(),
|
||||||
|
AccountID: newPeerTemplate.AccountID,
|
||||||
|
Key: currentWireGuardPubKey,
|
||||||
|
UserID: newPeerTemplate.UserID,
|
||||||
|
IP: newPeerTemplate.IP,
|
||||||
|
Meta: newPeerTemplate.Meta,
|
||||||
|
Name: newPeerTemplate.Name,
|
||||||
|
DNSLabel: newPeerTemplate.DNSLabel,
|
||||||
|
Status: &nbpeer.PeerStatus{Connected: false, LastSeen: time.Now()},
|
||||||
|
SSHEnabled: newPeerTemplate.SSHEnabled,
|
||||||
|
}
|
||||||
|
// add peer manually to bypass creation during login stage
|
||||||
|
if sk.AllowExtraDNSLabels {
|
||||||
|
currentPeer.ExtraDNSLabels = newPeerTemplate.ExtraDNSLabels
|
||||||
|
}
|
||||||
|
_, _, _, err = am.AddPeer(context.Background(), tc.setupKey, "", currentPeer)
|
||||||
|
require.NoError(t, err, "Expected no error when adding peer with setup key: %s", tc.setupKey)
|
||||||
|
|
||||||
|
loginInput := types.PeerLogin{
|
||||||
|
WireGuardPubKey: currentWireGuardPubKey,
|
||||||
|
SSHKey: "test-ssh-key",
|
||||||
|
Meta: baseMeta,
|
||||||
|
UserID: "",
|
||||||
|
SetupKey: tc.setupKey,
|
||||||
|
ConnectionIP: net.ParseIP("192.0.2.100"),
|
||||||
|
}
|
||||||
|
|
||||||
|
if tc.expectExtraDNSLabelsMismatch {
|
||||||
|
loginInput.ExtraDNSLabels = tc.extraDNSLabels
|
||||||
|
}
|
||||||
|
|
||||||
|
loggedinPeer, networkMap, postureChecks, loginErr := am.LoginPeer(context.Background(), loginInput)
|
||||||
|
if tc.expectLoginError {
|
||||||
|
require.Error(t, loginErr, "Expected an error during LoginPeer with setup key: %s", tc.setupKey)
|
||||||
|
assert.Contains(t, loginErr.Error(), tc.expectedErrorMsgSubstring, "Error message mismatch")
|
||||||
|
assert.Nil(t, loggedinPeer, "LoggedinPeer should be nil on error")
|
||||||
|
assert.Nil(t, networkMap, "NetworkMap should be nil on error")
|
||||||
|
assert.Nil(t, postureChecks, "PostureChecks should be empty or nil on error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
require.NoError(t, loginErr, "Expected no error during LoginPeer with setup key: %s", tc.setupKey)
|
||||||
|
assert.NotNil(t, loggedinPeer, "loggedinPeer should not be nil on success")
|
||||||
|
if tc.expectExtraDNSLabelsMismatch {
|
||||||
|
assert.NotEqual(t, tc.extraDNSLabels, loggedinPeer.ExtraDNSLabels, "ExtraDNSLabels should not match on loggedinPeer")
|
||||||
|
assert.Equal(t, currentPeer.ExtraDNSLabels, loggedinPeer.ExtraDNSLabels, "ExtraDNSLabels mismatch on loggedinPeer")
|
||||||
|
} else {
|
||||||
|
assert.Equal(t, currentPeer.ExtraDNSLabels, loggedinPeer.ExtraDNSLabels, "ExtraDNSLabels mismatch on loggedinPeer")
|
||||||
|
}
|
||||||
|
assert.NotNil(t, networkMap, "networkMap should not be nil on success")
|
||||||
|
|
||||||
|
assert.Equal(t, existingAccountID, loggedinPeer.AccountID, "AccountID mismatch for logged peer")
|
||||||
|
|
||||||
|
peerFromStore, err := s.GetPeerByPeerPubKey(context.Background(), store.LockingStrengthShare, loginInput.WireGuardPubKey)
|
||||||
|
require.NoError(t, err, "Failed to get peer by pub key: %s", loginInput.WireGuardPubKey)
|
||||||
|
assert.Equal(t, existingAccountID, peerFromStore.AccountID, "AccountID mismatch for peer from store")
|
||||||
|
assert.Equal(t, loggedinPeer.ID, peerFromStore.ID, "Peer ID mismatch between loggedinPeer and peerFromStore")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPeerAccountPeersUpdate(t *testing.T) {
|
func TestPeerAccountPeersUpdate(t *testing.T) {
|
||||||
manager, account, peer1, peer2, peer3 := setupNetworkMapTest(t)
|
manager, account, peer1, peer2, peer3 := setupNetworkMapTest(t)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
CREATE TABLE `accounts` (`id` text,`created_by` text,`created_at` datetime,`domain` text,`domain_category` text,`is_domain_primary_account` numeric,`network_identifier` text,`network_net` text,`network_dns` text,`network_serial` integer,`dns_settings_disabled_management_groups` text,`settings_peer_login_expiration_enabled` numeric,`settings_peer_login_expiration` integer,`settings_regular_users_view_blocked` numeric,`settings_groups_propagation_enabled` numeric,`settings_jwt_groups_enabled` numeric,`settings_jwt_groups_claim_name` text,`settings_jwt_allow_groups` text,`settings_extra_peer_approval_enabled` numeric,`settings_extra_integrated_validator_groups` text,PRIMARY KEY (`id`));
|
CREATE TABLE `accounts` (`id` text,`created_by` text,`created_at` datetime,`domain` text,`domain_category` text,`is_domain_primary_account` numeric,`network_identifier` text,`network_net` text,`network_dns` text,`network_serial` integer,`dns_settings_disabled_management_groups` text,`settings_peer_login_expiration_enabled` numeric,`settings_peer_login_expiration` integer,`settings_regular_users_view_blocked` numeric,`settings_groups_propagation_enabled` numeric,`settings_jwt_groups_enabled` numeric,`settings_jwt_groups_claim_name` text,`settings_jwt_allow_groups` text,`settings_extra_peer_approval_enabled` numeric,`settings_extra_integrated_validator_groups` text,PRIMARY KEY (`id`));
|
||||||
CREATE TABLE `setup_keys` (`id` text,`account_id` text,`key` text,`name` text,`type` text,`created_at` datetime,`expires_at` datetime,`updated_at` datetime,`revoked` numeric,`used_times` integer,`last_used` datetime DEFAULT NULL,`auto_groups` text,`usage_limit` integer,`ephemeral` numeric,PRIMARY KEY (`id`),CONSTRAINT `fk_accounts_setup_keys_g` FOREIGN KEY (`account_id`) REFERENCES `accounts`(`id`));
|
CREATE TABLE `setup_keys` (`id` text,`account_id` text,`key` text,`name` text,`type` text,`created_at` datetime,`expires_at` datetime,`updated_at` datetime,`revoked` numeric,`used_times` integer,`last_used` datetime DEFAULT NULL,`auto_groups` text,`usage_limit` integer,`ephemeral` numeric,`allow_extra_dns_labels` numeric,PRIMARY KEY (`id`),CONSTRAINT `fk_accounts_setup_keys_g` FOREIGN KEY (`account_id`) REFERENCES `accounts`(`id`));
|
||||||
CREATE TABLE `peers` (`id` text,`account_id` text,`key` text,`setup_key` text,`ip` text,`meta_hostname` text,`meta_go_os` text,`meta_kernel` text,`meta_core` text,`meta_platform` text,`meta_os` text,`meta_os_version` text,`meta_wt_version` text,`meta_ui_version` text,`meta_kernel_version` text,`meta_network_addresses` text,`meta_system_serial_number` text,`meta_system_product_name` text,`meta_system_manufacturer` text,`meta_environment` text,`meta_files` text,`name` text,`dns_label` text,`peer_status_last_seen` datetime,`peer_status_connected` numeric,`peer_status_login_expired` numeric,`peer_status_requires_approval` numeric,`user_id` text,`ssh_key` text,`ssh_enabled` numeric,`login_expiration_enabled` numeric,`last_login` datetime,`created_at` datetime,`ephemeral` numeric,`location_connection_ip` text,`location_country_code` text,`location_city_name` text,`location_geo_name_id` integer,PRIMARY KEY (`id`),CONSTRAINT `fk_accounts_peers_g` FOREIGN KEY (`account_id`) REFERENCES `accounts`(`id`));
|
CREATE TABLE `peers` (`id` text,`account_id` text,`key` text,`setup_key` text,`ip` text,`meta_hostname` text,`meta_go_os` text,`meta_kernel` text,`meta_core` text,`meta_platform` text,`meta_os` text,`meta_os_version` text,`meta_wt_version` text,`meta_ui_version` text,`meta_kernel_version` text,`meta_network_addresses` text,`meta_system_serial_number` text,`meta_system_product_name` text,`meta_system_manufacturer` text,`meta_environment` text,`meta_files` text,`name` text,`dns_label` text,`peer_status_last_seen` datetime,`peer_status_connected` numeric,`peer_status_login_expired` numeric,`peer_status_requires_approval` numeric,`user_id` text,`ssh_key` text,`ssh_enabled` numeric,`login_expiration_enabled` numeric,`last_login` datetime,`created_at` datetime,`ephemeral` numeric,`location_connection_ip` text,`location_country_code` text,`location_city_name` text,`location_geo_name_id` integer,PRIMARY KEY (`id`),CONSTRAINT `fk_accounts_peers_g` FOREIGN KEY (`account_id`) REFERENCES `accounts`(`id`));
|
||||||
CREATE TABLE `users` (`id` text,`account_id` text,`role` text,`is_service_user` numeric,`non_deletable` numeric,`service_user_name` text,`auto_groups` text,`blocked` numeric,`last_login` datetime DEFAULT NULL,`created_at` datetime,`issued` text DEFAULT "api",`integration_ref_id` integer,`integration_ref_integration_type` text,PRIMARY KEY (`id`),CONSTRAINT `fk_accounts_users_g` FOREIGN KEY (`account_id`) REFERENCES `accounts`(`id`));
|
CREATE TABLE `users` (`id` text,`account_id` text,`role` text,`is_service_user` numeric,`non_deletable` numeric,`service_user_name` text,`auto_groups` text,`blocked` numeric,`last_login` datetime DEFAULT NULL,`created_at` datetime,`issued` text DEFAULT "api",`integration_ref_id` integer,`integration_ref_integration_type` text,PRIMARY KEY (`id`),CONSTRAINT `fk_accounts_users_g` FOREIGN KEY (`account_id`) REFERENCES `accounts`(`id`));
|
||||||
CREATE TABLE `personal_access_tokens` (`id` text,`user_id` text,`name` text,`hashed_token` text,`expiration_date` datetime,`created_by` text,`created_at` datetime,`last_used` datetime,PRIMARY KEY (`id`),CONSTRAINT `fk_users_pa_ts_g` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`));
|
CREATE TABLE `personal_access_tokens` (`id` text,`user_id` text,`name` text,`hashed_token` text,`expiration_date` datetime,`created_by` text,`created_at` datetime,`last_used` datetime,PRIMARY KEY (`id`),CONSTRAINT `fk_users_pa_ts_g` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`));
|
||||||
@@ -26,8 +26,9 @@ CREATE INDEX `idx_name_server_groups_account_id` ON `name_server_groups`(`accoun
|
|||||||
CREATE INDEX `idx_posture_checks_account_id` ON `posture_checks`(`account_id`);
|
CREATE INDEX `idx_posture_checks_account_id` ON `posture_checks`(`account_id`);
|
||||||
|
|
||||||
INSERT INTO accounts VALUES('bf1c8084-ba50-4ce7-9439-34653001fc3b','edafee4e-63fb-11ec-90d6-0242ac120003','2024-10-02 16:01:38.210000+02:00','test.com','private',1,'af1c8024-ha40-4ce2-9418-34653101fc3c','{"IP":"100.64.0.0","Mask":"//8AAA=="}','',0,'[]',0,86400000000000,0,0,0,'',NULL,NULL,NULL);
|
INSERT INTO accounts VALUES('bf1c8084-ba50-4ce7-9439-34653001fc3b','edafee4e-63fb-11ec-90d6-0242ac120003','2024-10-02 16:01:38.210000+02:00','test.com','private',1,'af1c8024-ha40-4ce2-9418-34653101fc3c','{"IP":"100.64.0.0","Mask":"//8AAA=="}','',0,'[]',0,86400000000000,0,0,0,'',NULL,NULL,NULL);
|
||||||
INSERT INTO setup_keys VALUES('A2C8E62B-38F5-4553-B31E-DD66C696CEBB','bf1c8084-ba50-4ce7-9439-34653001fc3b','A2C8E62B-38F5-4553-B31E-DD66C696CEBB','Default key','reusable','2021-08-19 20:46:20.005936822+02:00','2321-09-18 20:46:20.005936822+02:00','2021-08-19 20:46:20.005936822+02:00',0,0,NULL,'["cfefqs706sqkneg59g2g"]',0,0);
|
INSERT INTO setup_keys VALUES('A2C8E62B-38F5-4553-B31E-DD66C696CEBB','bf1c8084-ba50-4ce7-9439-34653001fc3b','A2C8E62B-38F5-4553-B31E-DD66C696CEBB','Default key','reusable','2021-08-19 20:46:20.005936822+02:00','2321-09-18 20:46:20.005936822+02:00','2021-08-19 20:46:20.005936822+02:00',0,0,NULL,'["cfefqs706sqkneg59g2g"]',0,0,0);
|
||||||
INSERT INTO setup_keys VALUES('A2C8E62B-38F5-4553-B31E-DD66C696CEBC','bf1c8084-ba50-4ce7-9439-34653001fc3b','A2C8E62B-38F5-4553-B31E-DD66C696CEBC','Faulty key with non existing group','reusable','2021-08-19 20:46:20.005936822+02:00','2321-09-18 20:46:20.005936822+02:00','2021-08-19 20:46:20.005936822+02:00',0,0,NULL,'["abcd"]',0,0);
|
INSERT INTO setup_keys VALUES('A2C8E62B-38F5-4553-B31E-DD66C696CEBD','bf1c8084-ba50-4ce7-9439-34653001fc3b','A2C8E62B-38F5-4553-B31E-DD66C696CEBD','Default key with extra DNS labels','reusable','2021-08-19 20:46:20.005936822+02:00','2321-09-18 20:46:20.005936822+02:00','2021-08-19 20:46:20.005936822+02:00',0,0,NULL,'["cfefqs706sqkneg59g2g"]',0,0,1);
|
||||||
|
INSERT INTO setup_keys VALUES('A2C8E62B-38F5-4553-B31E-DD66C696CEBC','bf1c8084-ba50-4ce7-9439-34653001fc3b','A2C8E62B-38F5-4553-B31E-DD66C696CEBC','Faulty key with non existing group','reusable','2021-08-19 20:46:20.005936822+02:00','2321-09-18 20:46:20.005936822+02:00','2021-08-19 20:46:20.005936822+02:00',0,0,NULL,'["abcd"]',0,0,0);
|
||||||
INSERT INTO users VALUES('edafee4e-63fb-11ec-90d6-0242ac120003','bf1c8084-ba50-4ce7-9439-34653001fc3b','admin',0,0,'','["cfefqs706sqkneg59g3g"]',0,NULL,'2024-10-02 16:01:38.210678+02:00','api',0,'');
|
INSERT INTO users VALUES('edafee4e-63fb-11ec-90d6-0242ac120003','bf1c8084-ba50-4ce7-9439-34653001fc3b','admin',0,0,'','["cfefqs706sqkneg59g3g"]',0,NULL,'2024-10-02 16:01:38.210678+02:00','api',0,'');
|
||||||
INSERT INTO users VALUES('f4f6d672-63fb-11ec-90d6-0242ac120003','bf1c8084-ba50-4ce7-9439-34653001fc3b','user',0,0,'','[]',0,NULL,'2024-10-02 16:01:38.210678+02:00','api',0,'');
|
INSERT INTO users VALUES('f4f6d672-63fb-11ec-90d6-0242ac120003','bf1c8084-ba50-4ce7-9439-34653001fc3b','user',0,0,'','[]',0,NULL,'2024-10-02 16:01:38.210678+02:00','api',0,'');
|
||||||
INSERT INTO personal_access_tokens VALUES('9dj38s35-63fb-11ec-90d6-0242ac120003','f4f6d672-63fb-11ec-90d6-0242ac120003','','SoMeHaShEdToKeN','2023-02-27 00:00:00+00:00','user','2023-01-01 00:00:00+00:00','2023-02-01 00:00:00+00:00');
|
INSERT INTO personal_access_tokens VALUES('9dj38s35-63fb-11ec-90d6-0242ac120003','f4f6d672-63fb-11ec-90d6-0242ac120003','','SoMeHaShEdToKeN','2023-02-27 00:00:00+00:00','user','2023-01-01 00:00:00+00:00','2023-02-01 00:00:00+00:00');
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package types
|
|||||||
import (
|
import (
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
|
||||||
|
"github.com/netbirdio/netbird/management/client/common"
|
||||||
"github.com/netbirdio/netbird/management/server/idp"
|
"github.com/netbirdio/netbird/management/server/idp"
|
||||||
"github.com/netbirdio/netbird/util"
|
"github.com/netbirdio/netbird/util"
|
||||||
)
|
)
|
||||||
@@ -156,6 +157,8 @@ type ProviderConfig struct {
|
|||||||
RedirectURLs []string
|
RedirectURLs []string
|
||||||
// DisablePromptLogin makes the PKCE flow to not prompt the user for login
|
// DisablePromptLogin makes the PKCE flow to not prompt the user for login
|
||||||
DisablePromptLogin bool
|
DisablePromptLogin bool
|
||||||
|
// LoginFlag is used to configure the PKCE flow login behavior
|
||||||
|
LoginFlag common.LoginFlag
|
||||||
}
|
}
|
||||||
|
|
||||||
// StoreConfig contains Store configuration
|
// StoreConfig contains Store configuration
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ func (registry *Registry) Register(peer *Peer) {
|
|||||||
p, loaded := registry.Peers.LoadOrStore(peer.Id, peer)
|
p, loaded := registry.Peers.LoadOrStore(peer.Id, peer)
|
||||||
if loaded {
|
if loaded {
|
||||||
pp := p.(*Peer)
|
pp := p.(*Peer)
|
||||||
log.Warnf("peer [%s] is already registered [new streamID %d, previous StreamID %d]. Will override stream.",
|
log.Tracef("peer [%s] is already registered [new streamID %d, previous StreamID %d]. Will override stream.",
|
||||||
peer.Id, peer.StreamID, pp.StreamID)
|
peer.Id, peer.StreamID, pp.StreamID)
|
||||||
registry.Peers.Store(peer.Id, peer)
|
registry.Peers.Store(peer.Id, peer)
|
||||||
return
|
return
|
||||||
@@ -104,7 +104,7 @@ func (registry *Registry) Deregister(peer *Peer) {
|
|||||||
pp := p.(*Peer)
|
pp := p.(*Peer)
|
||||||
if peer.StreamID < pp.StreamID {
|
if peer.StreamID < pp.StreamID {
|
||||||
registry.Peers.Store(peer.Id, p)
|
registry.Peers.Store(peer.Id, p)
|
||||||
log.Warnf("attempted to remove newer registered stream of a peer [%s] [newer streamID %d, previous StreamID %d]. Ignoring.",
|
log.Debugf("attempted to remove newer registered stream of a peer [%s] [newer streamID %d, previous StreamID %d]. Ignoring.",
|
||||||
peer.Id, pp.StreamID, peer.StreamID)
|
peer.Id, pp.StreamID, peer.StreamID)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,8 @@ package server
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/netbirdio/signal-dispatcher/dispatcher"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
"go.opentelemetry.io/otel/metric"
|
"go.opentelemetry.io/otel/metric"
|
||||||
@@ -15,6 +13,8 @@ import (
|
|||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
gproto "google.golang.org/protobuf/proto"
|
gproto "google.golang.org/protobuf/proto"
|
||||||
|
|
||||||
|
"github.com/netbirdio/signal-dispatcher/dispatcher"
|
||||||
|
|
||||||
"github.com/netbirdio/netbird/signal/metrics"
|
"github.com/netbirdio/netbird/signal/metrics"
|
||||||
"github.com/netbirdio/netbird/signal/peer"
|
"github.com/netbirdio/netbird/signal/peer"
|
||||||
"github.com/netbirdio/netbird/signal/proto"
|
"github.com/netbirdio/netbird/signal/proto"
|
||||||
@@ -28,10 +28,11 @@ const (
|
|||||||
labelTypeStream = "stream"
|
labelTypeStream = "stream"
|
||||||
labelTypeMessage = "message"
|
labelTypeMessage = "message"
|
||||||
|
|
||||||
labelError = "error"
|
labelError = "error"
|
||||||
labelErrorMissingId = "missing_id"
|
labelErrorMissingId = "missing_id"
|
||||||
labelErrorMissingMeta = "missing_meta"
|
labelErrorMissingMeta = "missing_meta"
|
||||||
labelErrorFailedHeader = "failed_header"
|
labelErrorFailedHeader = "failed_header"
|
||||||
|
labelErrorFailedRegistration = "failed_registration"
|
||||||
|
|
||||||
labelRegistrationStatus = "status"
|
labelRegistrationStatus = "status"
|
||||||
labelRegistrationFound = "found"
|
labelRegistrationFound = "found"
|
||||||
@@ -69,7 +70,7 @@ func NewServer(ctx context.Context, meter metric.Meter) (*Server, error) {
|
|||||||
|
|
||||||
// Send forwards a message to the signal peer
|
// Send forwards a message to the signal peer
|
||||||
func (s *Server) Send(ctx context.Context, msg *proto.EncryptedMessage) (*proto.EncryptedMessage, error) {
|
func (s *Server) Send(ctx context.Context, msg *proto.EncryptedMessage) (*proto.EncryptedMessage, error) {
|
||||||
log.Debugf("received a new message to send from peer [%s] to peer [%s]", msg.Key, msg.RemoteKey)
|
log.Tracef("received a new message to send from peer [%s] to peer [%s]", msg.Key, msg.RemoteKey)
|
||||||
|
|
||||||
if _, found := s.registry.Get(msg.RemoteKey); found {
|
if _, found := s.registry.Get(msg.RemoteKey); found {
|
||||||
s.forwardMessageToPeer(ctx, msg)
|
s.forwardMessageToPeer(ctx, msg)
|
||||||
@@ -98,28 +99,9 @@ func (s *Server) ConnectStream(stream proto.SignalExchange_ConnectStreamServer)
|
|||||||
|
|
||||||
log.Debugf("peer connected [%s] [streamID %d] ", p.Id, p.StreamID)
|
log.Debugf("peer connected [%s] [streamID %d] ", p.Id, p.StreamID)
|
||||||
|
|
||||||
for {
|
<-stream.Context().Done()
|
||||||
select {
|
log.Debugf("peer stream closing [%s] [streamID %d] ", p.Id, p.StreamID)
|
||||||
case <-stream.Context().Done():
|
return nil
|
||||||
log.Debugf("stream closed for peer [%s] [streamID %d] due to context cancellation", p.Id, p.StreamID)
|
|
||||||
return stream.Context().Err()
|
|
||||||
default:
|
|
||||||
// read incoming messages
|
|
||||||
msg, err := stream.Recv()
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
} else if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("Received a response from peer [%s] to peer [%s]", msg.Key, msg.RemoteKey)
|
|
||||||
|
|
||||||
_, err = s.dispatcher.SendMessage(stream.Context(), msg)
|
|
||||||
if err != nil {
|
|
||||||
log.Debugf("error while sending message from peer [%s] to peer [%s] %v", msg.Key, msg.RemoteKey, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) RegisterPeer(stream proto.SignalExchange_ConnectStreamServer) (*peer.Peer, error) {
|
func (s *Server) RegisterPeer(stream proto.SignalExchange_ConnectStreamServer) (*peer.Peer, error) {
|
||||||
@@ -138,7 +120,12 @@ func (s *Server) RegisterPeer(stream proto.SignalExchange_ConnectStreamServer) (
|
|||||||
|
|
||||||
p := peer.NewPeer(id[0], stream)
|
p := peer.NewPeer(id[0], stream)
|
||||||
s.registry.Register(p)
|
s.registry.Register(p)
|
||||||
s.dispatcher.ListenForMessages(stream.Context(), p.Id, s.forwardMessageToPeer)
|
err := s.dispatcher.ListenForMessages(stream.Context(), p.Id, s.forwardMessageToPeer)
|
||||||
|
if err != nil {
|
||||||
|
s.metrics.RegistrationFailures.Add(stream.Context(), 1, metric.WithAttributes(attribute.String(labelError, labelErrorFailedRegistration)))
|
||||||
|
log.Errorf("error while registering message listener for peer [%s] %v", p.Id, err)
|
||||||
|
return nil, status.Errorf(codes.Internal, "error while registering message listener")
|
||||||
|
}
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +136,7 @@ func (s *Server) DeregisterPeer(p *peer.Peer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) forwardMessageToPeer(ctx context.Context, msg *proto.EncryptedMessage) {
|
func (s *Server) forwardMessageToPeer(ctx context.Context, msg *proto.EncryptedMessage) {
|
||||||
log.Debugf("forwarding a new message from peer [%s] to peer [%s]", msg.Key, msg.RemoteKey)
|
log.Tracef("forwarding a new message from peer [%s] to peer [%s]", msg.Key, msg.RemoteKey)
|
||||||
getRegistrationStart := time.Now()
|
getRegistrationStart := time.Now()
|
||||||
|
|
||||||
// lookup the target peer where the message is going to
|
// lookup the target peer where the message is going to
|
||||||
@@ -168,7 +155,7 @@ func (s *Server) forwardMessageToPeer(ctx context.Context, msg *proto.EncryptedM
|
|||||||
|
|
||||||
// forward the message to the target peer
|
// forward the message to the target peer
|
||||||
if err := dstPeer.Stream.Send(msg); err != nil {
|
if err := dstPeer.Stream.Send(msg); err != nil {
|
||||||
log.Warnf("error while forwarding message from peer [%s] to peer [%s] %v", msg.Key, msg.RemoteKey, err)
|
log.Tracef("error while forwarding message from peer [%s] to peer [%s] %v", msg.Key, msg.RemoteKey, err)
|
||||||
// todo respond to the sender?
|
// todo respond to the sender?
|
||||||
s.metrics.MessageForwardFailures.Add(ctx, 1, metric.WithAttributes(attribute.String(labelType, labelTypeError)))
|
s.metrics.MessageForwardFailures.Add(ctx, 1, metric.WithAttributes(attribute.String(labelType, labelTypeError)))
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user