mirror of
https://github.com/netbirdio/netbird.git
synced 2025-01-31 18:39:31 +01:00
Merge branch 'main' into feature/optimize-network-map-updates
This commit is contained in:
commit
f3ec200985
9
.github/ISSUE_TEMPLATE/bug-issue-report.md
vendored
9
.github/ISSUE_TEMPLATE/bug-issue-report.md
vendored
@ -31,9 +31,14 @@ Please specify whether you use NetBird Cloud or self-host NetBird's control plan
|
|||||||
|
|
||||||
`netbird version`
|
`netbird version`
|
||||||
|
|
||||||
**NetBird status -d output:**
|
**NetBird status -dA output:**
|
||||||
|
|
||||||
If applicable, add the `netbird status -d' command output.
|
If applicable, add the `netbird status -dA' command output.
|
||||||
|
|
||||||
|
**Do you face any client issues on desktop?**
|
||||||
|
|
||||||
|
Please provide the file created by `netbird debug for 1m -AS`.
|
||||||
|
We advise reviewing the anonymized files for any remaining PII.
|
||||||
|
|
||||||
**Screenshots**
|
**Screenshots**
|
||||||
|
|
||||||
|
@ -39,6 +39,11 @@ var loginCmd = &cobra.Command{
|
|||||||
ctx = context.WithValue(ctx, system.DeviceNameCtxKey, hostName)
|
ctx = context.WithValue(ctx, system.DeviceNameCtxKey, hostName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
providedSetupKey, err := getSetupKey()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// workaround to run without service
|
// workaround to run without service
|
||||||
if logFile == "console" {
|
if logFile == "console" {
|
||||||
err = handleRebrand(cmd)
|
err = handleRebrand(cmd)
|
||||||
@ -62,7 +67,7 @@ var loginCmd = &cobra.Command{
|
|||||||
|
|
||||||
config, _ = internal.UpdateOldManagementURL(ctx, config, configPath)
|
config, _ = internal.UpdateOldManagementURL(ctx, config, configPath)
|
||||||
|
|
||||||
err = foregroundLogin(ctx, cmd, config, setupKey)
|
err = foregroundLogin(ctx, cmd, config, providedSetupKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("foreground login failed: %v", err)
|
return fmt.Errorf("foreground login failed: %v", err)
|
||||||
}
|
}
|
||||||
@ -81,7 +86,7 @@ var loginCmd = &cobra.Command{
|
|||||||
client := proto.NewDaemonServiceClient(conn)
|
client := proto.NewDaemonServiceClient(conn)
|
||||||
|
|
||||||
loginRequest := proto.LoginRequest{
|
loginRequest := proto.LoginRequest{
|
||||||
SetupKey: setupKey,
|
SetupKey: providedSetupKey,
|
||||||
ManagementUrl: managementURL,
|
ManagementUrl: managementURL,
|
||||||
IsLinuxDesktopClient: isLinuxRunningDesktop(),
|
IsLinuxDesktopClient: isLinuxRunningDesktop(),
|
||||||
Hostname: hostName,
|
Hostname: hostName,
|
||||||
|
@ -56,6 +56,7 @@ var (
|
|||||||
managementURL string
|
managementURL string
|
||||||
adminURL string
|
adminURL string
|
||||||
setupKey string
|
setupKey string
|
||||||
|
setupKeyPath string
|
||||||
hostName string
|
hostName string
|
||||||
preSharedKey string
|
preSharedKey string
|
||||||
natExternalIPs []string
|
natExternalIPs []string
|
||||||
@ -128,6 +129,8 @@ func init() {
|
|||||||
rootCmd.PersistentFlags().StringVarP(&logLevel, "log-level", "l", "info", "sets Netbird log level")
|
rootCmd.PersistentFlags().StringVarP(&logLevel, "log-level", "l", "info", "sets Netbird log level")
|
||||||
rootCmd.PersistentFlags().StringVar(&logFile, "log-file", defaultLogFile, "sets Netbird log path. If console is specified the log will be output to stdout. If syslog is specified the log will be sent to syslog daemon.")
|
rootCmd.PersistentFlags().StringVar(&logFile, "log-file", defaultLogFile, "sets Netbird log path. If console is specified the log will be output to stdout. If syslog is specified the log will be sent to syslog daemon.")
|
||||||
rootCmd.PersistentFlags().StringVarP(&setupKey, "setup-key", "k", "", "Setup key obtained from the Management Service Dashboard (used to register peer)")
|
rootCmd.PersistentFlags().StringVarP(&setupKey, "setup-key", "k", "", "Setup key obtained from the Management Service Dashboard (used to register peer)")
|
||||||
|
rootCmd.PersistentFlags().StringVar(&setupKeyPath, "setup-key-file", "", "The path to a setup key obtained from the Management Service Dashboard (used to register peer) This is ignored if the setup-key flag is provided.")
|
||||||
|
rootCmd.MarkFlagsMutuallyExclusive("setup-key", "setup-key-file")
|
||||||
rootCmd.PersistentFlags().StringVar(&preSharedKey, preSharedKeyFlag, "", "Sets Wireguard PreSharedKey property. If set, then only peers that have the same key can communicate.")
|
rootCmd.PersistentFlags().StringVar(&preSharedKey, preSharedKeyFlag, "", "Sets Wireguard PreSharedKey property. If set, then only peers that have the same key can communicate.")
|
||||||
rootCmd.PersistentFlags().StringVarP(&hostName, "hostname", "n", "", "Sets a custom hostname for the device")
|
rootCmd.PersistentFlags().StringVarP(&hostName, "hostname", "n", "", "Sets a custom hostname for the device")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&anonymizeFlag, "anonymize", "A", false, "anonymize IP addresses and non-netbird.io domains in logs and status output")
|
rootCmd.PersistentFlags().BoolVarP(&anonymizeFlag, "anonymize", "A", false, "anonymize IP addresses and non-netbird.io domains in logs and status output")
|
||||||
@ -253,6 +256,21 @@ var CLIBackOffSettings = &backoff.ExponentialBackOff{
|
|||||||
Clock: backoff.SystemClock,
|
Clock: backoff.SystemClock,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getSetupKey() (string, error) {
|
||||||
|
if setupKeyPath != "" && setupKey == "" {
|
||||||
|
return getSetupKeyFromFile(setupKeyPath)
|
||||||
|
}
|
||||||
|
return setupKey, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSetupKeyFromFile(setupKeyPath string) (string, error) {
|
||||||
|
data, err := os.ReadFile(setupKeyPath)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to read setup key file: %v", err)
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(string(data)), nil
|
||||||
|
}
|
||||||
|
|
||||||
func handleRebrand(cmd *cobra.Command) error {
|
func handleRebrand(cmd *cobra.Command) error {
|
||||||
var err error
|
var err error
|
||||||
if logFile == defaultLogFile {
|
if logFile == defaultLogFile {
|
||||||
|
@ -147,6 +147,11 @@ func runInForegroundMode(ctx context.Context, cmd *cobra.Command) error {
|
|||||||
ic.DNSRouteInterval = &dnsRouteInterval
|
ic.DNSRouteInterval = &dnsRouteInterval
|
||||||
}
|
}
|
||||||
|
|
||||||
|
providedSetupKey, err := getSetupKey()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
config, err := internal.UpdateOrCreateConfig(ic)
|
config, err := internal.UpdateOrCreateConfig(ic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("get config file: %v", err)
|
return fmt.Errorf("get config file: %v", err)
|
||||||
@ -154,7 +159,7 @@ func runInForegroundMode(ctx context.Context, cmd *cobra.Command) error {
|
|||||||
|
|
||||||
config, _ = internal.UpdateOldManagementURL(ctx, config, configPath)
|
config, _ = internal.UpdateOldManagementURL(ctx, config, configPath)
|
||||||
|
|
||||||
err = foregroundLogin(ctx, cmd, config, setupKey)
|
err = foregroundLogin(ctx, cmd, config, providedSetupKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("foreground login failed: %v", err)
|
return fmt.Errorf("foreground login failed: %v", err)
|
||||||
}
|
}
|
||||||
@ -199,8 +204,13 @@ func runInDaemonMode(ctx context.Context, cmd *cobra.Command) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
providedSetupKey, err := getSetupKey()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
loginRequest := proto.LoginRequest{
|
loginRequest := proto.LoginRequest{
|
||||||
SetupKey: setupKey,
|
SetupKey: providedSetupKey,
|
||||||
ManagementUrl: managementURL,
|
ManagementUrl: managementURL,
|
||||||
AdminURL: adminURL,
|
AdminURL: adminURL,
|
||||||
NatExternalIPs: natExternalIPs,
|
NatExternalIPs: natExternalIPs,
|
||||||
|
@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -40,6 +41,36 @@ func TestUpDaemon(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test the setup-key-file flag.
|
||||||
|
tempFile, err := os.CreateTemp("", "setup-key")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("could not create temp file, got error %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer os.Remove(tempFile.Name())
|
||||||
|
if _, err := tempFile.Write([]byte("A2C8E62B-38F5-4553-B31E-DD66C696CEBB")); err != nil {
|
||||||
|
t.Errorf("could not write to temp file, got error %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := tempFile.Close(); err != nil {
|
||||||
|
t.Errorf("unable to close file, got error %v", err)
|
||||||
|
}
|
||||||
|
rootCmd.SetArgs([]string{
|
||||||
|
"login",
|
||||||
|
"--daemon-addr", "tcp://" + cliAddr,
|
||||||
|
"--setup-key-file", tempFile.Name(),
|
||||||
|
"--log-file", "",
|
||||||
|
})
|
||||||
|
if err := rootCmd.Execute(); err != nil {
|
||||||
|
t.Errorf("expected no error while running up command, got %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
time.Sleep(time.Second * 3)
|
||||||
|
if status, err := state.Status(); err != nil && status != internal.StatusIdle {
|
||||||
|
t.Errorf("wrong status after login: %s, %v", internal.StatusIdle, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
rootCmd.SetArgs([]string{
|
rootCmd.SetArgs([]string{
|
||||||
"up",
|
"up",
|
||||||
"--daemon-addr", "tcp://" + cliAddr,
|
"--daemon-addr", "tcp://" + cliAddr,
|
||||||
|
@ -922,7 +922,7 @@ func (a *Account) UserGroupsAddToPeers(userID string, groups ...string) {
|
|||||||
func (a *Account) UserGroupsRemoveFromPeers(userID string, groups ...string) {
|
func (a *Account) UserGroupsRemoveFromPeers(userID string, groups ...string) {
|
||||||
for _, gid := range groups {
|
for _, gid := range groups {
|
||||||
group, ok := a.Groups[gid]
|
group, ok := a.Groups[gid]
|
||||||
if !ok {
|
if !ok || group.Name == "All" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
update := make([]string, 0, len(group.Peers))
|
update := make([]string, 0, len(group.Peers))
|
||||||
|
@ -223,10 +223,8 @@ func (am *DefaultAccountManager) CreateSetupKey(ctx context.Context, accountID s
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, group := range autoGroups {
|
if err := validateSetupKeyAutoGroups(account, autoGroups); err != nil {
|
||||||
if _, ok := account.Groups[group]; !ok {
|
return nil, err
|
||||||
return nil, status.Errorf(status.NotFound, "group %s doesn't exist", group)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setupKey := GenerateSetupKey(keyName, keyType, keyDuration, autoGroups, usageLimit, ephemeral)
|
setupKey := GenerateSetupKey(keyName, keyType, keyDuration, autoGroups, usageLimit, ephemeral)
|
||||||
@ -279,6 +277,10 @@ func (am *DefaultAccountManager) SaveSetupKey(ctx context.Context, accountID str
|
|||||||
return nil, status.Errorf(status.NotFound, "setup key not found")
|
return nil, status.Errorf(status.NotFound, "setup key not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := validateSetupKeyAutoGroups(account, keyToSave.AutoGroups); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// only auto groups, revoked status, and name can be updated for now
|
// only auto groups, revoked status, and name can be updated for now
|
||||||
newKey := oldKey.Copy()
|
newKey := oldKey.Copy()
|
||||||
newKey.Name = keyToSave.Name
|
newKey.Name = keyToSave.Name
|
||||||
@ -399,3 +401,16 @@ func (am *DefaultAccountManager) GetSetupKey(ctx context.Context, accountID, use
|
|||||||
|
|
||||||
return foundKey, nil
|
return foundKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateSetupKeyAutoGroups(account *Account, autoGroups []string) error {
|
||||||
|
for _, group := range autoGroups {
|
||||||
|
g, ok := account.Groups[group]
|
||||||
|
if !ok {
|
||||||
|
return status.Errorf(status.NotFound, "group %s doesn't exist", group)
|
||||||
|
}
|
||||||
|
if g.Name == "All" {
|
||||||
|
return status.Errorf(status.InvalidArgument, "can't add All group to the setup key")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -26,10 +26,17 @@ func TestDefaultAccountManager_SaveSetupKey(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = manager.SaveGroup(context.Background(), account.Id, userID, &nbgroup.Group{
|
err = manager.SaveGroups(context.Background(), account.Id, userID, []*nbgroup.Group{
|
||||||
ID: "group_1",
|
{
|
||||||
Name: "group_name_1",
|
ID: "group_1",
|
||||||
Peers: []string{},
|
Name: "group_name_1",
|
||||||
|
Peers: []string{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "group_2",
|
||||||
|
Name: "group_name_2",
|
||||||
|
Peers: []string{},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -70,6 +77,19 @@ func TestDefaultAccountManager_SaveSetupKey(t *testing.T) {
|
|||||||
assert.NotEmpty(t, ev.Meta["key"])
|
assert.NotEmpty(t, ev.Meta["key"])
|
||||||
assert.Equal(t, userID, ev.InitiatorID)
|
assert.Equal(t, userID, ev.InitiatorID)
|
||||||
assert.Equal(t, key.Id, ev.TargetID)
|
assert.Equal(t, key.Id, ev.TargetID)
|
||||||
|
|
||||||
|
groupAll, err := account.GetGroupAll()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// saving setup key with All group assigned to auto groups should return error
|
||||||
|
autoGroups = append(autoGroups, groupAll.ID)
|
||||||
|
_, err = manager.SaveSetupKey(context.Background(), account.Id, &SetupKey{
|
||||||
|
Id: key.Id,
|
||||||
|
Name: newKeyName,
|
||||||
|
Revoked: revoked,
|
||||||
|
AutoGroups: autoGroups,
|
||||||
|
}, userID)
|
||||||
|
assert.Error(t, err, "should not save setup key with All group assigned in auto groups")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDefaultAccountManager_CreateSetupKey(t *testing.T) {
|
func TestDefaultAccountManager_CreateSetupKey(t *testing.T) {
|
||||||
@ -102,6 +122,9 @@ func TestDefaultAccountManager_CreateSetupKey(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
groupAll, err := account.GetGroupAll()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
type testCase struct {
|
type testCase struct {
|
||||||
name string
|
name string
|
||||||
|
|
||||||
@ -134,8 +157,14 @@ func TestDefaultAccountManager_CreateSetupKey(t *testing.T) {
|
|||||||
expectedGroups: []string{"FAKE"},
|
expectedGroups: []string{"FAKE"},
|
||||||
expectedFailure: true,
|
expectedFailure: true,
|
||||||
}
|
}
|
||||||
|
testCase3 := testCase{
|
||||||
|
name: "Create Setup Key should fail because of All group",
|
||||||
|
expectedKeyName: "my-test-key",
|
||||||
|
expectedGroups: []string{groupAll.ID},
|
||||||
|
expectedFailure: true,
|
||||||
|
}
|
||||||
|
|
||||||
for _, tCase := range []testCase{testCase1, testCase2} {
|
for _, tCase := range []testCase{testCase1, testCase2, testCase3} {
|
||||||
t.Run(tCase.name, func(t *testing.T) {
|
t.Run(tCase.name, func(t *testing.T) {
|
||||||
key, err := manager.CreateSetupKey(context.Background(), account.Id, tCase.expectedKeyName, SetupKeyReusable, expiresIn,
|
key, err := manager.CreateSetupKey(context.Background(), account.Id, tCase.expectedKeyName, SetupKeyReusable, expiresIn,
|
||||||
tCase.expectedGroups, SetupKeyUnlimitedUsage, userID, false)
|
tCase.expectedGroups, SetupKeyUnlimitedUsage, userID, false)
|
||||||
|
@ -944,10 +944,14 @@ func validateUserUpdate(account *Account, initiatorUser, oldUser, update *User)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, newGroupID := range update.AutoGroups {
|
for _, newGroupID := range update.AutoGroups {
|
||||||
if _, ok := account.Groups[newGroupID]; !ok {
|
group, ok := account.Groups[newGroupID]
|
||||||
|
if !ok {
|
||||||
return status.Errorf(status.InvalidArgument, "provided group ID %s in the user %s update doesn't exist",
|
return status.Errorf(status.InvalidArgument, "provided group ID %s in the user %s update doesn't exist",
|
||||||
newGroupID, update.Id)
|
newGroupID, update.Id)
|
||||||
}
|
}
|
||||||
|
if group.Name == "All" {
|
||||||
|
return status.Errorf(status.InvalidArgument, "can't add All group to the user")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
Loading…
Reference in New Issue
Block a user