mirror of
https://github.com/netbirdio/netbird.git
synced 2025-08-17 02:21:47 +02:00
[client] Add --disable-update-settings flag to the service (#4335)
[client] Add --disable-update-settings flag to the service (#4335)
This commit is contained in:
@ -73,6 +73,7 @@ var (
|
|||||||
dnsRouteInterval time.Duration
|
dnsRouteInterval time.Duration
|
||||||
lazyConnEnabled bool
|
lazyConnEnabled bool
|
||||||
profilesDisabled bool
|
profilesDisabled bool
|
||||||
|
updateSettingsDisabled bool
|
||||||
|
|
||||||
rootCmd = &cobra.Command{
|
rootCmd = &cobra.Command{
|
||||||
Use: "netbird",
|
Use: "netbird",
|
||||||
|
@ -42,7 +42,8 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
serviceCmd.AddCommand(runCmd, startCmd, stopCmd, restartCmd, svcStatusCmd, installCmd, uninstallCmd, reconfigureCmd)
|
serviceCmd.AddCommand(runCmd, startCmd, stopCmd, restartCmd, svcStatusCmd, installCmd, uninstallCmd, reconfigureCmd)
|
||||||
serviceCmd.PersistentFlags().BoolVar(&profilesDisabled, "disable-profiles", false, "Disables profiles feature. If enabled, the client will not be able to change or edit any profile.")
|
serviceCmd.PersistentFlags().BoolVar(&profilesDisabled, "disable-profiles", false, "Disables profiles feature. If enabled, the client will not be able to change or edit any profile. To persist this setting, use: netbird service install --disable-profiles")
|
||||||
|
serviceCmd.PersistentFlags().BoolVar(&updateSettingsDisabled, "disable-update-settings", false, "Disables update settings feature. If enabled, the client will not be able to change or edit any settings. To persist this setting, use: netbird service install --disable-update-settings")
|
||||||
|
|
||||||
rootCmd.PersistentFlags().StringVarP(&serviceName, "service", "s", defaultServiceName, "Netbird system service name")
|
rootCmd.PersistentFlags().StringVarP(&serviceName, "service", "s", defaultServiceName, "Netbird system service name")
|
||||||
serviceEnvDesc := `Sets extra environment variables for the service. ` +
|
serviceEnvDesc := `Sets extra environment variables for the service. ` +
|
||||||
|
@ -61,7 +61,7 @@ func (p *program) Start(svc service.Service) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
serverInstance := server.New(p.ctx, util.FindFirstLogPath(logFiles), configPath, profilesDisabled)
|
serverInstance := server.New(p.ctx, util.FindFirstLogPath(logFiles), configPath, profilesDisabled, updateSettingsDisabled)
|
||||||
if err := serverInstance.Start(); err != nil {
|
if err := serverInstance.Start(); err != nil {
|
||||||
log.Fatalf("failed to start daemon: %v", err)
|
log.Fatalf("failed to start daemon: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,14 @@ func buildServiceArguments() []string {
|
|||||||
args = append(args, "--log-file", logFile)
|
args = append(args, "--log-file", logFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if profilesDisabled {
|
||||||
|
args = append(args, "--disable-profiles")
|
||||||
|
}
|
||||||
|
|
||||||
|
if updateSettingsDisabled {
|
||||||
|
args = append(args, "--disable-update-settings")
|
||||||
|
}
|
||||||
|
|
||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,8 +27,8 @@ import (
|
|||||||
|
|
||||||
clientProto "github.com/netbirdio/netbird/client/proto"
|
clientProto "github.com/netbirdio/netbird/client/proto"
|
||||||
client "github.com/netbirdio/netbird/client/server"
|
client "github.com/netbirdio/netbird/client/server"
|
||||||
mgmtProto "github.com/netbirdio/netbird/shared/management/proto"
|
|
||||||
mgmt "github.com/netbirdio/netbird/management/server"
|
mgmt "github.com/netbirdio/netbird/management/server"
|
||||||
|
mgmtProto "github.com/netbirdio/netbird/shared/management/proto"
|
||||||
sigProto "github.com/netbirdio/netbird/shared/signal/proto"
|
sigProto "github.com/netbirdio/netbird/shared/signal/proto"
|
||||||
sig "github.com/netbirdio/netbird/signal/server"
|
sig "github.com/netbirdio/netbird/signal/server"
|
||||||
)
|
)
|
||||||
@ -136,7 +136,7 @@ func startClientDaemon(
|
|||||||
s := grpc.NewServer()
|
s := grpc.NewServer()
|
||||||
|
|
||||||
server := client.New(ctx,
|
server := client.New(ctx,
|
||||||
"", "", false)
|
"", "", false, false)
|
||||||
if err := server.Start(); err != nil {
|
if err := server.Start(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -4430,6 +4430,94 @@ func (*LogoutResponse) Descriptor() ([]byte, []int) {
|
|||||||
return file_daemon_proto_rawDescGZIP(), []int{66}
|
return file_daemon_proto_rawDescGZIP(), []int{66}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetFeaturesRequest struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *GetFeaturesRequest) Reset() {
|
||||||
|
*x = GetFeaturesRequest{}
|
||||||
|
mi := &file_daemon_proto_msgTypes[67]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *GetFeaturesRequest) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*GetFeaturesRequest) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *GetFeaturesRequest) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_daemon_proto_msgTypes[67]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use GetFeaturesRequest.ProtoReflect.Descriptor instead.
|
||||||
|
func (*GetFeaturesRequest) Descriptor() ([]byte, []int) {
|
||||||
|
return file_daemon_proto_rawDescGZIP(), []int{67}
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetFeaturesResponse struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
DisableProfiles bool `protobuf:"varint,1,opt,name=disable_profiles,json=disableProfiles,proto3" json:"disable_profiles,omitempty"`
|
||||||
|
DisableUpdateSettings bool `protobuf:"varint,2,opt,name=disable_update_settings,json=disableUpdateSettings,proto3" json:"disable_update_settings,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *GetFeaturesResponse) Reset() {
|
||||||
|
*x = GetFeaturesResponse{}
|
||||||
|
mi := &file_daemon_proto_msgTypes[68]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *GetFeaturesResponse) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*GetFeaturesResponse) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *GetFeaturesResponse) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_daemon_proto_msgTypes[68]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use GetFeaturesResponse.ProtoReflect.Descriptor instead.
|
||||||
|
func (*GetFeaturesResponse) Descriptor() ([]byte, []int) {
|
||||||
|
return file_daemon_proto_rawDescGZIP(), []int{68}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *GetFeaturesResponse) GetDisableProfiles() bool {
|
||||||
|
if x != nil {
|
||||||
|
return x.DisableProfiles
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *GetFeaturesResponse) GetDisableUpdateSettings() bool {
|
||||||
|
if x != nil {
|
||||||
|
return x.DisableUpdateSettings
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
type PortInfo_Range struct {
|
type PortInfo_Range struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
Start uint32 `protobuf:"varint,1,opt,name=start,proto3" json:"start,omitempty"`
|
Start uint32 `protobuf:"varint,1,opt,name=start,proto3" json:"start,omitempty"`
|
||||||
@ -4440,7 +4528,7 @@ type PortInfo_Range struct {
|
|||||||
|
|
||||||
func (x *PortInfo_Range) Reset() {
|
func (x *PortInfo_Range) Reset() {
|
||||||
*x = PortInfo_Range{}
|
*x = PortInfo_Range{}
|
||||||
mi := &file_daemon_proto_msgTypes[68]
|
mi := &file_daemon_proto_msgTypes[70]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@ -4452,7 +4540,7 @@ func (x *PortInfo_Range) String() string {
|
|||||||
func (*PortInfo_Range) ProtoMessage() {}
|
func (*PortInfo_Range) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *PortInfo_Range) ProtoReflect() protoreflect.Message {
|
func (x *PortInfo_Range) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_daemon_proto_msgTypes[68]
|
mi := &file_daemon_proto_msgTypes[70]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@ -4872,7 +4960,11 @@ const file_daemon_proto_rawDesc = "" +
|
|||||||
"\busername\x18\x02 \x01(\tH\x01R\busername\x88\x01\x01B\x0e\n" +
|
"\busername\x18\x02 \x01(\tH\x01R\busername\x88\x01\x01B\x0e\n" +
|
||||||
"\f_profileNameB\v\n" +
|
"\f_profileNameB\v\n" +
|
||||||
"\t_username\"\x10\n" +
|
"\t_username\"\x10\n" +
|
||||||
"\x0eLogoutResponse*b\n" +
|
"\x0eLogoutResponse\"\x14\n" +
|
||||||
|
"\x12GetFeaturesRequest\"x\n" +
|
||||||
|
"\x13GetFeaturesResponse\x12)\n" +
|
||||||
|
"\x10disable_profiles\x18\x01 \x01(\bR\x0fdisableProfiles\x126\n" +
|
||||||
|
"\x17disable_update_settings\x18\x02 \x01(\bR\x15disableUpdateSettings*b\n" +
|
||||||
"\bLogLevel\x12\v\n" +
|
"\bLogLevel\x12\v\n" +
|
||||||
"\aUNKNOWN\x10\x00\x12\t\n" +
|
"\aUNKNOWN\x10\x00\x12\t\n" +
|
||||||
"\x05PANIC\x10\x01\x12\t\n" +
|
"\x05PANIC\x10\x01\x12\t\n" +
|
||||||
@ -4881,7 +4973,7 @@ const file_daemon_proto_rawDesc = "" +
|
|||||||
"\x04WARN\x10\x04\x12\b\n" +
|
"\x04WARN\x10\x04\x12\b\n" +
|
||||||
"\x04INFO\x10\x05\x12\t\n" +
|
"\x04INFO\x10\x05\x12\t\n" +
|
||||||
"\x05DEBUG\x10\x06\x12\t\n" +
|
"\x05DEBUG\x10\x06\x12\t\n" +
|
||||||
"\x05TRACE\x10\a2\xc5\x0f\n" +
|
"\x05TRACE\x10\a2\x8f\x10\n" +
|
||||||
"\rDaemonService\x126\n" +
|
"\rDaemonService\x126\n" +
|
||||||
"\x05Login\x12\x14.daemon.LoginRequest\x1a\x15.daemon.LoginResponse\"\x00\x12K\n" +
|
"\x05Login\x12\x14.daemon.LoginRequest\x1a\x15.daemon.LoginResponse\"\x00\x12K\n" +
|
||||||
"\fWaitSSOLogin\x12\x1b.daemon.WaitSSOLoginRequest\x1a\x1c.daemon.WaitSSOLoginResponse\"\x00\x12-\n" +
|
"\fWaitSSOLogin\x12\x1b.daemon.WaitSSOLoginRequest\x1a\x1c.daemon.WaitSSOLoginResponse\"\x00\x12-\n" +
|
||||||
@ -4912,7 +5004,8 @@ const file_daemon_proto_rawDesc = "" +
|
|||||||
"\rRemoveProfile\x12\x1c.daemon.RemoveProfileRequest\x1a\x1d.daemon.RemoveProfileResponse\"\x00\x12K\n" +
|
"\rRemoveProfile\x12\x1c.daemon.RemoveProfileRequest\x1a\x1d.daemon.RemoveProfileResponse\"\x00\x12K\n" +
|
||||||
"\fListProfiles\x12\x1b.daemon.ListProfilesRequest\x1a\x1c.daemon.ListProfilesResponse\"\x00\x12W\n" +
|
"\fListProfiles\x12\x1b.daemon.ListProfilesRequest\x1a\x1c.daemon.ListProfilesResponse\"\x00\x12W\n" +
|
||||||
"\x10GetActiveProfile\x12\x1f.daemon.GetActiveProfileRequest\x1a .daemon.GetActiveProfileResponse\"\x00\x129\n" +
|
"\x10GetActiveProfile\x12\x1f.daemon.GetActiveProfileRequest\x1a .daemon.GetActiveProfileResponse\"\x00\x129\n" +
|
||||||
"\x06Logout\x12\x15.daemon.LogoutRequest\x1a\x16.daemon.LogoutResponse\"\x00B\bZ\x06/protob\x06proto3"
|
"\x06Logout\x12\x15.daemon.LogoutRequest\x1a\x16.daemon.LogoutResponse\"\x00\x12H\n" +
|
||||||
|
"\vGetFeatures\x12\x1a.daemon.GetFeaturesRequest\x1a\x1b.daemon.GetFeaturesResponse\"\x00B\bZ\x06/protob\x06proto3"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
file_daemon_proto_rawDescOnce sync.Once
|
file_daemon_proto_rawDescOnce sync.Once
|
||||||
@ -4927,7 +5020,7 @@ func file_daemon_proto_rawDescGZIP() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var file_daemon_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
|
var file_daemon_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
|
||||||
var file_daemon_proto_msgTypes = make([]protoimpl.MessageInfo, 70)
|
var file_daemon_proto_msgTypes = make([]protoimpl.MessageInfo, 72)
|
||||||
var file_daemon_proto_goTypes = []any{
|
var file_daemon_proto_goTypes = []any{
|
||||||
(LogLevel)(0), // 0: daemon.LogLevel
|
(LogLevel)(0), // 0: daemon.LogLevel
|
||||||
(SystemEvent_Severity)(0), // 1: daemon.SystemEvent.Severity
|
(SystemEvent_Severity)(0), // 1: daemon.SystemEvent.Severity
|
||||||
@ -4999,18 +5092,20 @@ var file_daemon_proto_goTypes = []any{
|
|||||||
(*GetActiveProfileResponse)(nil), // 67: daemon.GetActiveProfileResponse
|
(*GetActiveProfileResponse)(nil), // 67: daemon.GetActiveProfileResponse
|
||||||
(*LogoutRequest)(nil), // 68: daemon.LogoutRequest
|
(*LogoutRequest)(nil), // 68: daemon.LogoutRequest
|
||||||
(*LogoutResponse)(nil), // 69: daemon.LogoutResponse
|
(*LogoutResponse)(nil), // 69: daemon.LogoutResponse
|
||||||
nil, // 70: daemon.Network.ResolvedIPsEntry
|
(*GetFeaturesRequest)(nil), // 70: daemon.GetFeaturesRequest
|
||||||
(*PortInfo_Range)(nil), // 71: daemon.PortInfo.Range
|
(*GetFeaturesResponse)(nil), // 71: daemon.GetFeaturesResponse
|
||||||
nil, // 72: daemon.SystemEvent.MetadataEntry
|
nil, // 72: daemon.Network.ResolvedIPsEntry
|
||||||
(*durationpb.Duration)(nil), // 73: google.protobuf.Duration
|
(*PortInfo_Range)(nil), // 73: daemon.PortInfo.Range
|
||||||
(*timestamppb.Timestamp)(nil), // 74: google.protobuf.Timestamp
|
nil, // 74: daemon.SystemEvent.MetadataEntry
|
||||||
|
(*durationpb.Duration)(nil), // 75: google.protobuf.Duration
|
||||||
|
(*timestamppb.Timestamp)(nil), // 76: google.protobuf.Timestamp
|
||||||
}
|
}
|
||||||
var file_daemon_proto_depIdxs = []int32{
|
var file_daemon_proto_depIdxs = []int32{
|
||||||
73, // 0: daemon.LoginRequest.dnsRouteInterval:type_name -> google.protobuf.Duration
|
75, // 0: daemon.LoginRequest.dnsRouteInterval:type_name -> google.protobuf.Duration
|
||||||
22, // 1: daemon.StatusResponse.fullStatus:type_name -> daemon.FullStatus
|
22, // 1: daemon.StatusResponse.fullStatus:type_name -> daemon.FullStatus
|
||||||
74, // 2: daemon.PeerState.connStatusUpdate:type_name -> google.protobuf.Timestamp
|
76, // 2: daemon.PeerState.connStatusUpdate:type_name -> google.protobuf.Timestamp
|
||||||
74, // 3: daemon.PeerState.lastWireguardHandshake:type_name -> google.protobuf.Timestamp
|
76, // 3: daemon.PeerState.lastWireguardHandshake:type_name -> google.protobuf.Timestamp
|
||||||
73, // 4: daemon.PeerState.latency:type_name -> google.protobuf.Duration
|
75, // 4: daemon.PeerState.latency:type_name -> google.protobuf.Duration
|
||||||
19, // 5: daemon.FullStatus.managementState:type_name -> daemon.ManagementState
|
19, // 5: daemon.FullStatus.managementState:type_name -> daemon.ManagementState
|
||||||
18, // 6: daemon.FullStatus.signalState:type_name -> daemon.SignalState
|
18, // 6: daemon.FullStatus.signalState:type_name -> daemon.SignalState
|
||||||
17, // 7: daemon.FullStatus.localPeerState:type_name -> daemon.LocalPeerState
|
17, // 7: daemon.FullStatus.localPeerState:type_name -> daemon.LocalPeerState
|
||||||
@ -5019,8 +5114,8 @@ var file_daemon_proto_depIdxs = []int32{
|
|||||||
21, // 10: daemon.FullStatus.dns_servers:type_name -> daemon.NSGroupState
|
21, // 10: daemon.FullStatus.dns_servers:type_name -> daemon.NSGroupState
|
||||||
52, // 11: daemon.FullStatus.events:type_name -> daemon.SystemEvent
|
52, // 11: daemon.FullStatus.events:type_name -> daemon.SystemEvent
|
||||||
28, // 12: daemon.ListNetworksResponse.routes:type_name -> daemon.Network
|
28, // 12: daemon.ListNetworksResponse.routes:type_name -> daemon.Network
|
||||||
70, // 13: daemon.Network.resolvedIPs:type_name -> daemon.Network.ResolvedIPsEntry
|
72, // 13: daemon.Network.resolvedIPs:type_name -> daemon.Network.ResolvedIPsEntry
|
||||||
71, // 14: daemon.PortInfo.range:type_name -> daemon.PortInfo.Range
|
73, // 14: daemon.PortInfo.range:type_name -> daemon.PortInfo.Range
|
||||||
29, // 15: daemon.ForwardingRule.destinationPort:type_name -> daemon.PortInfo
|
29, // 15: daemon.ForwardingRule.destinationPort:type_name -> daemon.PortInfo
|
||||||
29, // 16: daemon.ForwardingRule.translatedPort:type_name -> daemon.PortInfo
|
29, // 16: daemon.ForwardingRule.translatedPort:type_name -> daemon.PortInfo
|
||||||
30, // 17: daemon.ForwardingRulesResponse.rules:type_name -> daemon.ForwardingRule
|
30, // 17: daemon.ForwardingRulesResponse.rules:type_name -> daemon.ForwardingRule
|
||||||
@ -5031,10 +5126,10 @@ var file_daemon_proto_depIdxs = []int32{
|
|||||||
49, // 22: daemon.TracePacketResponse.stages:type_name -> daemon.TraceStage
|
49, // 22: daemon.TracePacketResponse.stages:type_name -> daemon.TraceStage
|
||||||
1, // 23: daemon.SystemEvent.severity:type_name -> daemon.SystemEvent.Severity
|
1, // 23: daemon.SystemEvent.severity:type_name -> daemon.SystemEvent.Severity
|
||||||
2, // 24: daemon.SystemEvent.category:type_name -> daemon.SystemEvent.Category
|
2, // 24: daemon.SystemEvent.category:type_name -> daemon.SystemEvent.Category
|
||||||
74, // 25: daemon.SystemEvent.timestamp:type_name -> google.protobuf.Timestamp
|
76, // 25: daemon.SystemEvent.timestamp:type_name -> google.protobuf.Timestamp
|
||||||
72, // 26: daemon.SystemEvent.metadata:type_name -> daemon.SystemEvent.MetadataEntry
|
74, // 26: daemon.SystemEvent.metadata:type_name -> daemon.SystemEvent.MetadataEntry
|
||||||
52, // 27: daemon.GetEventsResponse.events:type_name -> daemon.SystemEvent
|
52, // 27: daemon.GetEventsResponse.events:type_name -> daemon.SystemEvent
|
||||||
73, // 28: daemon.SetConfigRequest.dnsRouteInterval:type_name -> google.protobuf.Duration
|
75, // 28: daemon.SetConfigRequest.dnsRouteInterval:type_name -> google.protobuf.Duration
|
||||||
65, // 29: daemon.ListProfilesResponse.profiles:type_name -> daemon.Profile
|
65, // 29: daemon.ListProfilesResponse.profiles:type_name -> daemon.Profile
|
||||||
27, // 30: daemon.Network.ResolvedIPsEntry.value:type_name -> daemon.IPList
|
27, // 30: daemon.Network.ResolvedIPsEntry.value:type_name -> daemon.IPList
|
||||||
4, // 31: daemon.DaemonService.Login:input_type -> daemon.LoginRequest
|
4, // 31: daemon.DaemonService.Login:input_type -> daemon.LoginRequest
|
||||||
@ -5064,35 +5159,37 @@ var file_daemon_proto_depIdxs = []int32{
|
|||||||
63, // 55: daemon.DaemonService.ListProfiles:input_type -> daemon.ListProfilesRequest
|
63, // 55: daemon.DaemonService.ListProfiles:input_type -> daemon.ListProfilesRequest
|
||||||
66, // 56: daemon.DaemonService.GetActiveProfile:input_type -> daemon.GetActiveProfileRequest
|
66, // 56: daemon.DaemonService.GetActiveProfile:input_type -> daemon.GetActiveProfileRequest
|
||||||
68, // 57: daemon.DaemonService.Logout:input_type -> daemon.LogoutRequest
|
68, // 57: daemon.DaemonService.Logout:input_type -> daemon.LogoutRequest
|
||||||
5, // 58: daemon.DaemonService.Login:output_type -> daemon.LoginResponse
|
70, // 58: daemon.DaemonService.GetFeatures:input_type -> daemon.GetFeaturesRequest
|
||||||
7, // 59: daemon.DaemonService.WaitSSOLogin:output_type -> daemon.WaitSSOLoginResponse
|
5, // 59: daemon.DaemonService.Login:output_type -> daemon.LoginResponse
|
||||||
9, // 60: daemon.DaemonService.Up:output_type -> daemon.UpResponse
|
7, // 60: daemon.DaemonService.WaitSSOLogin:output_type -> daemon.WaitSSOLoginResponse
|
||||||
11, // 61: daemon.DaemonService.Status:output_type -> daemon.StatusResponse
|
9, // 61: daemon.DaemonService.Up:output_type -> daemon.UpResponse
|
||||||
13, // 62: daemon.DaemonService.Down:output_type -> daemon.DownResponse
|
11, // 62: daemon.DaemonService.Status:output_type -> daemon.StatusResponse
|
||||||
15, // 63: daemon.DaemonService.GetConfig:output_type -> daemon.GetConfigResponse
|
13, // 63: daemon.DaemonService.Down:output_type -> daemon.DownResponse
|
||||||
24, // 64: daemon.DaemonService.ListNetworks:output_type -> daemon.ListNetworksResponse
|
15, // 64: daemon.DaemonService.GetConfig:output_type -> daemon.GetConfigResponse
|
||||||
26, // 65: daemon.DaemonService.SelectNetworks:output_type -> daemon.SelectNetworksResponse
|
24, // 65: daemon.DaemonService.ListNetworks:output_type -> daemon.ListNetworksResponse
|
||||||
26, // 66: daemon.DaemonService.DeselectNetworks:output_type -> daemon.SelectNetworksResponse
|
26, // 66: daemon.DaemonService.SelectNetworks:output_type -> daemon.SelectNetworksResponse
|
||||||
31, // 67: daemon.DaemonService.ForwardingRules:output_type -> daemon.ForwardingRulesResponse
|
26, // 67: daemon.DaemonService.DeselectNetworks:output_type -> daemon.SelectNetworksResponse
|
||||||
33, // 68: daemon.DaemonService.DebugBundle:output_type -> daemon.DebugBundleResponse
|
31, // 68: daemon.DaemonService.ForwardingRules:output_type -> daemon.ForwardingRulesResponse
|
||||||
35, // 69: daemon.DaemonService.GetLogLevel:output_type -> daemon.GetLogLevelResponse
|
33, // 69: daemon.DaemonService.DebugBundle:output_type -> daemon.DebugBundleResponse
|
||||||
37, // 70: daemon.DaemonService.SetLogLevel:output_type -> daemon.SetLogLevelResponse
|
35, // 70: daemon.DaemonService.GetLogLevel:output_type -> daemon.GetLogLevelResponse
|
||||||
40, // 71: daemon.DaemonService.ListStates:output_type -> daemon.ListStatesResponse
|
37, // 71: daemon.DaemonService.SetLogLevel:output_type -> daemon.SetLogLevelResponse
|
||||||
42, // 72: daemon.DaemonService.CleanState:output_type -> daemon.CleanStateResponse
|
40, // 72: daemon.DaemonService.ListStates:output_type -> daemon.ListStatesResponse
|
||||||
44, // 73: daemon.DaemonService.DeleteState:output_type -> daemon.DeleteStateResponse
|
42, // 73: daemon.DaemonService.CleanState:output_type -> daemon.CleanStateResponse
|
||||||
46, // 74: daemon.DaemonService.SetSyncResponsePersistence:output_type -> daemon.SetSyncResponsePersistenceResponse
|
44, // 74: daemon.DaemonService.DeleteState:output_type -> daemon.DeleteStateResponse
|
||||||
50, // 75: daemon.DaemonService.TracePacket:output_type -> daemon.TracePacketResponse
|
46, // 75: daemon.DaemonService.SetSyncResponsePersistence:output_type -> daemon.SetSyncResponsePersistenceResponse
|
||||||
52, // 76: daemon.DaemonService.SubscribeEvents:output_type -> daemon.SystemEvent
|
50, // 76: daemon.DaemonService.TracePacket:output_type -> daemon.TracePacketResponse
|
||||||
54, // 77: daemon.DaemonService.GetEvents:output_type -> daemon.GetEventsResponse
|
52, // 77: daemon.DaemonService.SubscribeEvents:output_type -> daemon.SystemEvent
|
||||||
56, // 78: daemon.DaemonService.SwitchProfile:output_type -> daemon.SwitchProfileResponse
|
54, // 78: daemon.DaemonService.GetEvents:output_type -> daemon.GetEventsResponse
|
||||||
58, // 79: daemon.DaemonService.SetConfig:output_type -> daemon.SetConfigResponse
|
56, // 79: daemon.DaemonService.SwitchProfile:output_type -> daemon.SwitchProfileResponse
|
||||||
60, // 80: daemon.DaemonService.AddProfile:output_type -> daemon.AddProfileResponse
|
58, // 80: daemon.DaemonService.SetConfig:output_type -> daemon.SetConfigResponse
|
||||||
62, // 81: daemon.DaemonService.RemoveProfile:output_type -> daemon.RemoveProfileResponse
|
60, // 81: daemon.DaemonService.AddProfile:output_type -> daemon.AddProfileResponse
|
||||||
64, // 82: daemon.DaemonService.ListProfiles:output_type -> daemon.ListProfilesResponse
|
62, // 82: daemon.DaemonService.RemoveProfile:output_type -> daemon.RemoveProfileResponse
|
||||||
67, // 83: daemon.DaemonService.GetActiveProfile:output_type -> daemon.GetActiveProfileResponse
|
64, // 83: daemon.DaemonService.ListProfiles:output_type -> daemon.ListProfilesResponse
|
||||||
69, // 84: daemon.DaemonService.Logout:output_type -> daemon.LogoutResponse
|
67, // 84: daemon.DaemonService.GetActiveProfile:output_type -> daemon.GetActiveProfileResponse
|
||||||
58, // [58:85] is the sub-list for method output_type
|
69, // 85: daemon.DaemonService.Logout:output_type -> daemon.LogoutResponse
|
||||||
31, // [31:58] is the sub-list for method input_type
|
71, // 86: daemon.DaemonService.GetFeatures:output_type -> daemon.GetFeaturesResponse
|
||||||
|
59, // [59:87] is the sub-list for method output_type
|
||||||
|
31, // [31:59] is the sub-list for method input_type
|
||||||
31, // [31:31] is the sub-list for extension type_name
|
31, // [31:31] is the sub-list for extension type_name
|
||||||
31, // [31:31] is the sub-list for extension extendee
|
31, // [31:31] is the sub-list for extension extendee
|
||||||
0, // [0:31] is the sub-list for field type_name
|
0, // [0:31] is the sub-list for field type_name
|
||||||
@ -5120,7 +5217,7 @@ func file_daemon_proto_init() {
|
|||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_daemon_proto_rawDesc), len(file_daemon_proto_rawDesc)),
|
RawDescriptor: unsafe.Slice(unsafe.StringData(file_daemon_proto_rawDesc), len(file_daemon_proto_rawDesc)),
|
||||||
NumEnums: 3,
|
NumEnums: 3,
|
||||||
NumMessages: 70,
|
NumMessages: 72,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 1,
|
NumServices: 1,
|
||||||
},
|
},
|
||||||
|
@ -82,6 +82,8 @@ service DaemonService {
|
|||||||
|
|
||||||
// Logout disconnects from the network and deletes the peer from the management server
|
// Logout disconnects from the network and deletes the peer from the management server
|
||||||
rpc Logout(LogoutRequest) returns (LogoutResponse) {}
|
rpc Logout(LogoutRequest) returns (LogoutResponse) {}
|
||||||
|
|
||||||
|
rpc GetFeatures(GetFeaturesRequest) returns (GetFeaturesResponse) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -624,4 +626,11 @@ message LogoutRequest {
|
|||||||
optional string username = 2;
|
optional string username = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message LogoutResponse {}
|
message LogoutResponse {}
|
||||||
|
|
||||||
|
message GetFeaturesRequest{}
|
||||||
|
|
||||||
|
message GetFeaturesResponse{
|
||||||
|
bool disable_profiles = 1;
|
||||||
|
bool disable_update_settings = 2;
|
||||||
|
}
|
@ -63,6 +63,7 @@ type DaemonServiceClient interface {
|
|||||||
GetActiveProfile(ctx context.Context, in *GetActiveProfileRequest, opts ...grpc.CallOption) (*GetActiveProfileResponse, error)
|
GetActiveProfile(ctx context.Context, in *GetActiveProfileRequest, opts ...grpc.CallOption) (*GetActiveProfileResponse, error)
|
||||||
// Logout disconnects from the network and deletes the peer from the management server
|
// Logout disconnects from the network and deletes the peer from the management server
|
||||||
Logout(ctx context.Context, in *LogoutRequest, opts ...grpc.CallOption) (*LogoutResponse, error)
|
Logout(ctx context.Context, in *LogoutRequest, opts ...grpc.CallOption) (*LogoutResponse, error)
|
||||||
|
GetFeatures(ctx context.Context, in *GetFeaturesRequest, opts ...grpc.CallOption) (*GetFeaturesResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type daemonServiceClient struct {
|
type daemonServiceClient struct {
|
||||||
@ -339,6 +340,15 @@ func (c *daemonServiceClient) Logout(ctx context.Context, in *LogoutRequest, opt
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *daemonServiceClient) GetFeatures(ctx context.Context, in *GetFeaturesRequest, opts ...grpc.CallOption) (*GetFeaturesResponse, error) {
|
||||||
|
out := new(GetFeaturesResponse)
|
||||||
|
err := c.cc.Invoke(ctx, "/daemon.DaemonService/GetFeatures", in, out, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
// DaemonServiceServer is the server API for DaemonService service.
|
// DaemonServiceServer is the server API for DaemonService service.
|
||||||
// All implementations must embed UnimplementedDaemonServiceServer
|
// All implementations must embed UnimplementedDaemonServiceServer
|
||||||
// for forward compatibility
|
// for forward compatibility
|
||||||
@ -388,6 +398,7 @@ type DaemonServiceServer interface {
|
|||||||
GetActiveProfile(context.Context, *GetActiveProfileRequest) (*GetActiveProfileResponse, error)
|
GetActiveProfile(context.Context, *GetActiveProfileRequest) (*GetActiveProfileResponse, error)
|
||||||
// Logout disconnects from the network and deletes the peer from the management server
|
// Logout disconnects from the network and deletes the peer from the management server
|
||||||
Logout(context.Context, *LogoutRequest) (*LogoutResponse, error)
|
Logout(context.Context, *LogoutRequest) (*LogoutResponse, error)
|
||||||
|
GetFeatures(context.Context, *GetFeaturesRequest) (*GetFeaturesResponse, error)
|
||||||
mustEmbedUnimplementedDaemonServiceServer()
|
mustEmbedUnimplementedDaemonServiceServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,6 +487,9 @@ func (UnimplementedDaemonServiceServer) GetActiveProfile(context.Context, *GetAc
|
|||||||
func (UnimplementedDaemonServiceServer) Logout(context.Context, *LogoutRequest) (*LogoutResponse, error) {
|
func (UnimplementedDaemonServiceServer) Logout(context.Context, *LogoutRequest) (*LogoutResponse, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method Logout not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method Logout not implemented")
|
||||||
}
|
}
|
||||||
|
func (UnimplementedDaemonServiceServer) GetFeatures(context.Context, *GetFeaturesRequest) (*GetFeaturesResponse, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method GetFeatures not implemented")
|
||||||
|
}
|
||||||
func (UnimplementedDaemonServiceServer) mustEmbedUnimplementedDaemonServiceServer() {}
|
func (UnimplementedDaemonServiceServer) mustEmbedUnimplementedDaemonServiceServer() {}
|
||||||
|
|
||||||
// UnsafeDaemonServiceServer may be embedded to opt out of forward compatibility for this service.
|
// UnsafeDaemonServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||||
@ -978,6 +992,24 @@ func _DaemonService_Logout_Handler(srv interface{}, ctx context.Context, dec fun
|
|||||||
return interceptor(ctx, in, info, handler)
|
return interceptor(ctx, in, info, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _DaemonService_GetFeatures_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(GetFeaturesRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(DaemonServiceServer).GetFeatures(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: "/daemon.DaemonService/GetFeatures",
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(DaemonServiceServer).GetFeatures(ctx, req.(*GetFeaturesRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
// DaemonService_ServiceDesc is the grpc.ServiceDesc for DaemonService service.
|
// DaemonService_ServiceDesc is the grpc.ServiceDesc for DaemonService service.
|
||||||
// It's only intended for direct use with grpc.RegisterService,
|
// It's only intended for direct use with grpc.RegisterService,
|
||||||
// and not to be introspected or modified (even as a copy)
|
// and not to be introspected or modified (even as a copy)
|
||||||
@ -1089,6 +1121,10 @@ var DaemonService_ServiceDesc = grpc.ServiceDesc{
|
|||||||
MethodName: "Logout",
|
MethodName: "Logout",
|
||||||
Handler: _DaemonService_Logout_Handler,
|
Handler: _DaemonService_Logout_Handler,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MethodName: "GetFeatures",
|
||||||
|
Handler: _DaemonService_GetFeatures_Handler,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Streams: []grpc.StreamDesc{
|
Streams: []grpc.StreamDesc{
|
||||||
{
|
{
|
||||||
|
@ -46,8 +46,9 @@ const (
|
|||||||
defaultMaxRetryTime = 14 * 24 * time.Hour
|
defaultMaxRetryTime = 14 * 24 * time.Hour
|
||||||
defaultRetryMultiplier = 1.7
|
defaultRetryMultiplier = 1.7
|
||||||
|
|
||||||
errRestoreResidualState = "failed to restore residual state: %v"
|
errRestoreResidualState = "failed to restore residual state: %v"
|
||||||
errProfilesDisabled = "profiles are disabled, you cannot use this feature without profiles enabled"
|
errProfilesDisabled = "profiles are disabled, you cannot use this feature without profiles enabled"
|
||||||
|
errUpdateSettingsDisabled = "update settings are disabled, you cannot use this feature without update settings enabled"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrServiceNotUp = errors.New("service is not up")
|
var ErrServiceNotUp = errors.New("service is not up")
|
||||||
@ -74,8 +75,9 @@ type Server struct {
|
|||||||
persistSyncResponse bool
|
persistSyncResponse bool
|
||||||
isSessionActive atomic.Bool
|
isSessionActive atomic.Bool
|
||||||
|
|
||||||
profileManager *profilemanager.ServiceManager
|
profileManager *profilemanager.ServiceManager
|
||||||
profilesDisabled bool
|
profilesDisabled bool
|
||||||
|
updateSettingsDisabled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type oauthAuthFlow struct {
|
type oauthAuthFlow struct {
|
||||||
@ -86,14 +88,15 @@ type oauthAuthFlow struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// New server instance constructor.
|
// New server instance constructor.
|
||||||
func New(ctx context.Context, logFile string, configFile string, profilesDisabled bool) *Server {
|
func New(ctx context.Context, logFile string, configFile string, profilesDisabled bool, updateSettingsDisabled bool) *Server {
|
||||||
return &Server{
|
return &Server{
|
||||||
rootCtx: ctx,
|
rootCtx: ctx,
|
||||||
logFile: logFile,
|
logFile: logFile,
|
||||||
persistSyncResponse: true,
|
persistSyncResponse: true,
|
||||||
statusRecorder: peer.NewRecorder(""),
|
statusRecorder: peer.NewRecorder(""),
|
||||||
profileManager: profilemanager.NewServiceManager(configFile),
|
profileManager: profilemanager.NewServiceManager(configFile),
|
||||||
profilesDisabled: profilesDisabled,
|
profilesDisabled: profilesDisabled,
|
||||||
|
updateSettingsDisabled: updateSettingsDisabled,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,8 +325,8 @@ func (s *Server) SetConfig(callerCtx context.Context, msg *proto.SetConfigReques
|
|||||||
s.mutex.Lock()
|
s.mutex.Lock()
|
||||||
defer s.mutex.Unlock()
|
defer s.mutex.Unlock()
|
||||||
|
|
||||||
if s.checkProfilesDisabled() {
|
if s.checkUpdateSettingsDisabled() {
|
||||||
return nil, gstatus.Errorf(codes.Unavailable, errProfilesDisabled)
|
return nil, gstatus.Errorf(codes.Unavailable, errUpdateSettingsDisabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
profState := profilemanager.ActiveProfileState{
|
profState := profilemanager.ActiveProfileState{
|
||||||
@ -1330,10 +1333,31 @@ func (s *Server) GetActiveProfile(ctx context.Context, msg *proto.GetActiveProfi
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetFeatures returns the features supported by the daemon.
|
||||||
|
func (s *Server) GetFeatures(ctx context.Context, msg *proto.GetFeaturesRequest) (*proto.GetFeaturesResponse, error) {
|
||||||
|
s.mutex.Lock()
|
||||||
|
defer s.mutex.Unlock()
|
||||||
|
|
||||||
|
features := &proto.GetFeaturesResponse{
|
||||||
|
DisableProfiles: s.checkProfilesDisabled(),
|
||||||
|
DisableUpdateSettings: s.checkUpdateSettingsDisabled(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return features, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) checkProfilesDisabled() bool {
|
func (s *Server) checkProfilesDisabled() bool {
|
||||||
// Check if the environment variable is set to disable profiles
|
// Check if the environment variable is set to disable profiles
|
||||||
if s.profilesDisabled {
|
if s.profilesDisabled {
|
||||||
log.Warn("Profiles are disabled via NB_DISABLE_PROFILES environment variable")
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) checkUpdateSettingsDisabled() bool {
|
||||||
|
// Check if the environment variable is set to disable profiles
|
||||||
|
if s.updateSettingsDisabled {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@ import (
|
|||||||
"github.com/netbirdio/netbird/client/internal/peer"
|
"github.com/netbirdio/netbird/client/internal/peer"
|
||||||
"github.com/netbirdio/netbird/client/internal/profilemanager"
|
"github.com/netbirdio/netbird/client/internal/profilemanager"
|
||||||
daemonProto "github.com/netbirdio/netbird/client/proto"
|
daemonProto "github.com/netbirdio/netbird/client/proto"
|
||||||
mgmtProto "github.com/netbirdio/netbird/shared/management/proto"
|
|
||||||
"github.com/netbirdio/netbird/management/server"
|
"github.com/netbirdio/netbird/management/server"
|
||||||
"github.com/netbirdio/netbird/management/server/activity"
|
"github.com/netbirdio/netbird/management/server/activity"
|
||||||
"github.com/netbirdio/netbird/management/server/integrations/port_forwarding"
|
"github.com/netbirdio/netbird/management/server/integrations/port_forwarding"
|
||||||
@ -34,6 +33,7 @@ import (
|
|||||||
"github.com/netbirdio/netbird/management/server/store"
|
"github.com/netbirdio/netbird/management/server/store"
|
||||||
"github.com/netbirdio/netbird/management/server/telemetry"
|
"github.com/netbirdio/netbird/management/server/telemetry"
|
||||||
"github.com/netbirdio/netbird/management/server/types"
|
"github.com/netbirdio/netbird/management/server/types"
|
||||||
|
mgmtProto "github.com/netbirdio/netbird/shared/management/proto"
|
||||||
"github.com/netbirdio/netbird/shared/signal/proto"
|
"github.com/netbirdio/netbird/shared/signal/proto"
|
||||||
signalServer "github.com/netbirdio/netbird/signal/server"
|
signalServer "github.com/netbirdio/netbird/signal/server"
|
||||||
)
|
)
|
||||||
@ -95,7 +95,7 @@ func TestConnectWithRetryRuns(t *testing.T) {
|
|||||||
t.Fatalf("failed to set active profile state: %v", err)
|
t.Fatalf("failed to set active profile state: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s := New(ctx, "debug", "", false)
|
s := New(ctx, "debug", "", false, false)
|
||||||
|
|
||||||
s.config = config
|
s.config = config
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ func TestServer_Up(t *testing.T) {
|
|||||||
t.Fatalf("failed to set active profile state: %v", err)
|
t.Fatalf("failed to set active profile state: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s := New(ctx, "console", "", false)
|
s := New(ctx, "console", "", false, false)
|
||||||
|
|
||||||
err = s.Start()
|
err = s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -228,7 +228,7 @@ func TestServer_SubcribeEvents(t *testing.T) {
|
|||||||
t.Fatalf("failed to set active profile state: %v", err)
|
t.Fatalf("failed to set active profile state: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s := New(ctx, "console", "", false)
|
s := New(ctx, "console", "", false, false)
|
||||||
|
|
||||||
err = s.Start()
|
err = s.Start()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -392,6 +392,16 @@ func (s *serviceClient) updateIcon() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *serviceClient) showSettingsUI() {
|
func (s *serviceClient) showSettingsUI() {
|
||||||
|
// Check if update settings are disabled by daemon
|
||||||
|
features, err := s.getFeatures()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to get features from daemon: %v", err)
|
||||||
|
// Continue with default behavior if features can't be retrieved
|
||||||
|
} else if features != nil && features.DisableUpdateSettings {
|
||||||
|
log.Warn("Update settings are disabled by daemon")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// add settings window UI elements.
|
// add settings window UI elements.
|
||||||
s.wSettings = s.app.NewWindow("NetBird Settings")
|
s.wSettings = s.app.NewWindow("NetBird Settings")
|
||||||
s.wSettings.SetOnClosed(s.cancel)
|
s.wSettings.SetOnClosed(s.cancel)
|
||||||
@ -447,6 +457,17 @@ func (s *serviceClient) getSettingsForm() *widget.Form {
|
|||||||
},
|
},
|
||||||
SubmitText: "Save",
|
SubmitText: "Save",
|
||||||
OnSubmit: func() {
|
OnSubmit: func() {
|
||||||
|
// Check if update settings are disabled by daemon
|
||||||
|
features, err := s.getFeatures()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to get features from daemon: %v", err)
|
||||||
|
// Continue with default behavior if features can't be retrieved
|
||||||
|
} else if features != nil && features.DisableUpdateSettings {
|
||||||
|
log.Warn("Configuration updates are disabled by daemon")
|
||||||
|
dialog.ShowError(fmt.Errorf("Configuration updates are disabled by daemon"), s.wSettings)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if s.iPreSharedKey.Text != "" && s.iPreSharedKey.Text != censoredPreSharedKey {
|
if s.iPreSharedKey.Text != "" && s.iPreSharedKey.Text != censoredPreSharedKey {
|
||||||
// validate preSharedKey if it added
|
// validate preSharedKey if it added
|
||||||
if _, err := wgtypes.ParseKey(s.iPreSharedKey.Text); err != nil {
|
if _, err := wgtypes.ParseKey(s.iPreSharedKey.Text); err != nil {
|
||||||
@ -836,6 +857,20 @@ func (s *serviceClient) onTrayReady() {
|
|||||||
s.mCreateDebugBundle = s.mSettings.AddSubMenuItem("Create Debug Bundle", debugBundleMenuDescr)
|
s.mCreateDebugBundle = s.mSettings.AddSubMenuItem("Create Debug Bundle", debugBundleMenuDescr)
|
||||||
s.loadSettings()
|
s.loadSettings()
|
||||||
|
|
||||||
|
// Disable settings menu if update settings are disabled by daemon
|
||||||
|
features, err := s.getFeatures()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to get features from daemon: %v", err)
|
||||||
|
// Continue with default behavior if features can't be retrieved
|
||||||
|
} else {
|
||||||
|
if features != nil && features.DisableUpdateSettings {
|
||||||
|
s.setSettingsEnabled(false)
|
||||||
|
}
|
||||||
|
if features != nil && features.DisableProfiles {
|
||||||
|
s.mProfile.setEnabled(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s.exitNodeMu.Lock()
|
s.exitNodeMu.Lock()
|
||||||
s.mExitNode = systray.AddMenuItem("Exit Node", exitNodeMenuDescr)
|
s.mExitNode = systray.AddMenuItem("Exit Node", exitNodeMenuDescr)
|
||||||
s.mExitNode.Disable()
|
s.mExitNode.Disable()
|
||||||
@ -876,6 +911,10 @@ func (s *serviceClient) onTrayReady() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("error while updating status: %v", err)
|
log.Errorf("error while updating status: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check features periodically to handle daemon restarts
|
||||||
|
s.checkAndUpdateFeatures()
|
||||||
|
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -948,6 +987,59 @@ func (s *serviceClient) getSrvClient(timeout time.Duration) (proto.DaemonService
|
|||||||
return s.conn, nil
|
return s.conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setSettingsEnabled enables or disables the settings menu based on the provided state
|
||||||
|
func (s *serviceClient) setSettingsEnabled(enabled bool) {
|
||||||
|
if s.mSettings != nil {
|
||||||
|
if enabled {
|
||||||
|
s.mSettings.Enable()
|
||||||
|
s.mSettings.SetTooltip(settingsMenuDescr)
|
||||||
|
} else {
|
||||||
|
s.mSettings.Hide()
|
||||||
|
s.mSettings.SetTooltip("Settings are disabled by daemon")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkAndUpdateFeatures checks the current features and updates the UI accordingly
|
||||||
|
func (s *serviceClient) checkAndUpdateFeatures() {
|
||||||
|
features, err := s.getFeatures()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to get features from daemon: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update settings menu based on current features
|
||||||
|
if features != nil && features.DisableUpdateSettings {
|
||||||
|
s.setSettingsEnabled(false)
|
||||||
|
} else {
|
||||||
|
s.setSettingsEnabled(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update profile menu based on current features
|
||||||
|
if s.mProfile != nil {
|
||||||
|
if features != nil && features.DisableProfiles {
|
||||||
|
s.mProfile.setEnabled(false)
|
||||||
|
} else {
|
||||||
|
s.mProfile.setEnabled(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getFeatures from the daemon to determine which features are enabled/disabled.
|
||||||
|
func (s *serviceClient) getFeatures() (*proto.GetFeaturesResponse, error) {
|
||||||
|
conn, err := s.getSrvClient(failFastTimeout)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("get client for features: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
features, err := conn.GetFeatures(s.ctx, &proto.GetFeaturesRequest{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("get features from daemon: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return features, nil
|
||||||
|
}
|
||||||
|
|
||||||
// getSrvConfig from the service to show it in the settings window.
|
// getSrvConfig from the service to show it in the settings window.
|
||||||
func (s *serviceClient) getSrvConfig() {
|
func (s *serviceClient) getSrvConfig() {
|
||||||
s.managementURL = profilemanager.DefaultManagementURL
|
s.managementURL = profilemanager.DefaultManagementURL
|
||||||
|
@ -654,6 +654,19 @@ func (p *profileMenu) clear(profiles []Profile) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setEnabled enables or disables the profile menu based on the provided state
|
||||||
|
func (p *profileMenu) setEnabled(enabled bool) {
|
||||||
|
if p.profileMenuItem != nil {
|
||||||
|
if enabled {
|
||||||
|
p.profileMenuItem.Enable()
|
||||||
|
p.profileMenuItem.SetTooltip("")
|
||||||
|
} else {
|
||||||
|
p.profileMenuItem.Hide()
|
||||||
|
p.profileMenuItem.SetTooltip("Profiles are disabled by daemon")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (p *profileMenu) updateMenu() {
|
func (p *profileMenu) updateMenu() {
|
||||||
// check every second
|
// check every second
|
||||||
ticker := time.NewTicker(time.Second)
|
ticker := time.NewTicker(time.Second)
|
||||||
@ -662,7 +675,6 @@ func (p *profileMenu) updateMenu() {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
|
|
||||||
// get profilesList
|
// get profilesList
|
||||||
profiles, err := p.getProfiles()
|
profiles, err := p.getProfiles()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Reference in New Issue
Block a user