@@ -23,23 +23,29 @@ import (
23
23
24
24
var ErrClientAlreadyStarted = errors .New ("client already started" )
25
25
var ErrClientNotStarted = errors .New ("client not started" )
26
+ var ErrConfigNotInitialized = errors .New ("config not initialized" )
26
27
27
- // Client manages a netbird embedded client instance
28
+ // Client manages a netbird embedded client instance.
28
29
type Client struct {
29
30
deviceName string
30
31
config * profilemanager.Config
31
32
mu sync.Mutex
32
33
cancel context.CancelFunc
33
34
setupKey string
35
+ jwtToken string
34
36
connect * internal.ConnectClient
35
37
}
36
38
37
- // Options configures a new Client
39
+ // Options configures a new Client.
38
40
type Options struct {
39
41
// DeviceName is this peer's name in the network
40
42
DeviceName string
41
43
// SetupKey is used for authentication
42
44
SetupKey string
45
+ // JWTToken is used for JWT-based authentication
46
+ JWTToken string
47
+ // PrivateKey is used for direct private key authentication
48
+ PrivateKey string
43
49
// ManagementURL overrides the default management server URL
44
50
ManagementURL string
45
51
// PreSharedKey is the pre-shared key for the WireGuard interface
@@ -58,8 +64,35 @@ type Options struct {
58
64
DisableClientRoutes bool
59
65
}
60
66
61
- // New creates a new netbird embedded client
67
+ // validateCredentials checks that exactly one credential type is provided
68
+ func (opts * Options ) validateCredentials () error {
69
+ credentialsProvided := 0
70
+ if opts .SetupKey != "" {
71
+ credentialsProvided ++
72
+ }
73
+ if opts .JWTToken != "" {
74
+ credentialsProvided ++
75
+ }
76
+ if opts .PrivateKey != "" {
77
+ credentialsProvided ++
78
+ }
79
+
80
+ if credentialsProvided == 0 {
81
+ return fmt .Errorf ("one of SetupKey, JWTToken, or PrivateKey must be provided" )
82
+ }
83
+ if credentialsProvided > 1 {
84
+ return fmt .Errorf ("only one of SetupKey, JWTToken, or PrivateKey can be specified" )
85
+ }
86
+
87
+ return nil
88
+ }
89
+
90
+ // New creates a new netbird embedded client.
62
91
func New (opts Options ) (* Client , error ) {
92
+ if err := opts .validateCredentials (); err != nil {
93
+ return nil , err
94
+ }
95
+
63
96
if opts .LogOutput != nil {
64
97
logrus .SetOutput (opts .LogOutput )
65
98
}
@@ -107,9 +140,14 @@ func New(opts Options) (*Client, error) {
107
140
return nil , fmt .Errorf ("create config: %w" , err )
108
141
}
109
142
143
+ if opts .PrivateKey != "" {
144
+ config .PrivateKey = opts .PrivateKey
145
+ }
146
+
110
147
return & Client {
111
148
deviceName : opts .DeviceName ,
112
149
setupKey : opts .SetupKey ,
150
+ jwtToken : opts .JWTToken ,
113
151
config : config ,
114
152
}, nil
115
153
}
@@ -126,7 +164,7 @@ func (c *Client) Start(startCtx context.Context) error {
126
164
ctx := internal .CtxInitState (context .Background ())
127
165
// nolint:staticcheck
128
166
ctx = context .WithValue (ctx , system .DeviceNameCtxKey , c .deviceName )
129
- if err := internal .Login (ctx , c .config , c .setupKey , "" ); err != nil {
167
+ if err := internal .Login (ctx , c .config , c .setupKey , c . jwtToken ); err != nil {
130
168
return fmt .Errorf ("login: %w" , err )
131
169
}
132
170
@@ -187,6 +225,16 @@ func (c *Client) Stop(ctx context.Context) error {
187
225
}
188
226
}
189
227
228
+ // GetConfig returns a copy of the internal client config.
229
+ func (c * Client ) GetConfig () (profilemanager.Config , error ) {
230
+ c .mu .Lock ()
231
+ defer c .mu .Unlock ()
232
+ if c .config == nil {
233
+ return profilemanager.Config {}, ErrConfigNotInitialized
234
+ }
235
+ return * c .config , nil
236
+ }
237
+
190
238
// Dial dials a network address in the netbird network.
191
239
// Not applicable if the userspace networking mode is disabled.
192
240
func (c * Client ) Dial (ctx context.Context , network , address string ) (net.Conn , error ) {
@@ -211,7 +259,7 @@ func (c *Client) Dial(ctx context.Context, network, address string) (net.Conn, e
211
259
return nsnet .DialContext (ctx , network , address )
212
260
}
213
261
214
- // ListenTCP listens on the given address in the netbird network
262
+ // ListenTCP listens on the given address in the netbird network.
215
263
// Not applicable if the userspace networking mode is disabled.
216
264
func (c * Client ) ListenTCP (address string ) (net.Listener , error ) {
217
265
nsnet , addr , err := c .getNet ()
@@ -232,7 +280,7 @@ func (c *Client) ListenTCP(address string) (net.Listener, error) {
232
280
return nsnet .ListenTCP (tcpAddr )
233
281
}
234
282
235
- // ListenUDP listens on the given address in the netbird network
283
+ // ListenUDP listens on the given address in the netbird network.
236
284
// Not applicable if the userspace networking mode is disabled.
237
285
func (c * Client ) ListenUDP (address string ) (net.PacketConn , error ) {
238
286
nsnet , addr , err := c .getNet ()
0 commit comments