@@ -12,6 +12,7 @@ import (
12
12
"github.com/stacklok/toolhive/pkg/config"
13
13
"github.com/stacklok/toolhive/pkg/core"
14
14
"github.com/stacklok/toolhive/pkg/groups"
15
+ "github.com/stacklok/toolhive/pkg/logger"
15
16
"github.com/stacklok/toolhive/pkg/workloads"
16
17
)
17
18
@@ -104,6 +105,8 @@ func init() {
104
105
// TODO: Re-enable when group functionality is complete
105
106
//clientRegisterCmd.Flags().StringSliceVar(
106
107
// &groupNames, "group", []string{"default"}, "Only register workloads from specified groups")
108
+ //clientRemoveCmd.Flags().StringSliceVar(
109
+ // &groupNames, "group", []string{}, "Remove client from specified groups (if not set, removes all workloads from the client)")
107
110
}
108
111
109
112
func clientStatusCmdFunc (_ * cobra.Command , _ []string ) error {
@@ -208,21 +211,7 @@ func clientRemoveCmdFunc(cmd *cobra.Command, args []string) error {
208
211
clientType )
209
212
}
210
213
211
- ctx := cmd .Context ()
212
-
213
- manager , err := client .NewManager (ctx )
214
- if err != nil {
215
- return fmt .Errorf ("failed to create client manager: %w" , err )
216
- }
217
-
218
- err = manager .UnregisterClients (ctx , []client.Client {
219
- {Name : client .MCPClient (clientType )},
220
- })
221
- if err != nil {
222
- return fmt .Errorf ("failed to remove client %s: %w" , clientType , err )
223
- }
224
-
225
- return nil
214
+ return performClientRemoval (cmd .Context (), client.Client {Name : client .MCPClient (clientType )}, groupNames )
226
215
}
227
216
228
217
func listRegisteredClientsCmdFunc (_ * cobra.Command , _ []string ) error {
@@ -339,3 +328,114 @@ func registerClientsGlobally(
339
328
340
329
return nil
341
330
}
331
+
332
+ func performClientRemoval (ctx context.Context , clientToRemove client.Client , groupNames []string ) error {
333
+ clientManager , err := client .NewManager (ctx )
334
+ if err != nil {
335
+ return fmt .Errorf ("failed to create client manager: %w" , err )
336
+ }
337
+
338
+ workloadManager , err := workloads .NewManager (ctx )
339
+ if err != nil {
340
+ return fmt .Errorf ("failed to create workload manager: %w" , err )
341
+ }
342
+
343
+ runningWorkloads , err := workloadManager .ListWorkloads (ctx , false )
344
+ if err != nil {
345
+ return fmt .Errorf ("failed to list running workloads: %w" , err )
346
+ }
347
+
348
+ groupManager , err := groups .NewManager ()
349
+ if err != nil {
350
+ return fmt .Errorf ("failed to create group manager: %w" , err )
351
+ }
352
+
353
+ if len (groupNames ) > 0 {
354
+ return removeClientFromGroups (ctx , clientToRemove , groupNames , runningWorkloads , groupManager , clientManager )
355
+ }
356
+
357
+ return removeClientGlobally (ctx , clientToRemove , runningWorkloads , groupManager , clientManager )
358
+ }
359
+
360
+ func removeClientFromGroups (
361
+ ctx context.Context ,
362
+ clientToRemove client.Client ,
363
+ groupNames []string ,
364
+ runningWorkloads []core.Workload ,
365
+ groupManager groups.Manager ,
366
+ clientManager client.Manager ,
367
+ ) error {
368
+ fmt .Printf ("Filtering workloads to groups: %v\n " , groupNames )
369
+
370
+ // Remove client from specific groups only
371
+ filteredWorkloads , err := workloads .FilterByGroups (runningWorkloads , groupNames )
372
+ if err != nil {
373
+ return fmt .Errorf ("failed to filter workloads by groups: %w" , err )
374
+ }
375
+
376
+ // Remove the workloads from the client's configuration file
377
+ err = clientManager .UnregisterClients (ctx , []client.Client {clientToRemove }, filteredWorkloads )
378
+ if err != nil {
379
+ return fmt .Errorf ("failed to unregister client: %w" , err )
380
+ }
381
+
382
+ // Remove the client from the groups
383
+ err = groupManager .UnregisterClients (ctx , groupNames , []string {string (clientToRemove .Name )})
384
+ if err != nil {
385
+ return fmt .Errorf ("failed to unregister client from groups: %w" , err )
386
+ }
387
+
388
+ fmt .Printf ("Successfully removed client %s from groups: %v\n " , clientToRemove .Name , groupNames )
389
+
390
+ return nil
391
+ }
392
+
393
+ func removeClientGlobally (
394
+ ctx context.Context ,
395
+ clientToRemove client.Client ,
396
+ runningWorkloads []core.Workload ,
397
+ groupManager groups.Manager ,
398
+ clientManager client.Manager ,
399
+ ) error {
400
+ // Remove the workloads from the client's configuration file
401
+ err := clientManager .UnregisterClients (ctx , []client.Client {clientToRemove }, runningWorkloads )
402
+ if err != nil {
403
+ return fmt .Errorf ("failed to unregister client: %w" , err )
404
+ }
405
+
406
+ allGroups , err := groupManager .List (ctx )
407
+ if err != nil {
408
+ return fmt .Errorf ("failed to list groups: %w" , err )
409
+ }
410
+
411
+ if len (allGroups ) > 0 {
412
+ // Remove client from all groups first
413
+ allGroupNames := make ([]string , len (allGroups ))
414
+ for i , group := range allGroups {
415
+ allGroupNames [i ] = group .Name
416
+ }
417
+
418
+ err = groupManager .UnregisterClients (ctx , allGroupNames , []string {string (clientToRemove .Name )})
419
+ if err != nil {
420
+ return fmt .Errorf ("failed to unregister client from groups: %w" , err )
421
+ }
422
+ }
423
+
424
+ // Remove client from global registered clients list
425
+ err = config .UpdateConfig (func (c * config.Config ) {
426
+ for i , registeredClient := range c .Clients .RegisteredClients {
427
+ if registeredClient == string (clientToRemove .Name ) {
428
+ // Remove client from slice
429
+ c .Clients .RegisteredClients = append (c .Clients .RegisteredClients [:i ], c .Clients .RegisteredClients [i + 1 :]... )
430
+ logger .Infof ("Successfully unregistered client: %s\n " , clientToRemove .Name )
431
+ return
432
+ }
433
+ }
434
+ logger .Warnf ("Client %s was not found in registered clients list" , clientToRemove .Name )
435
+ })
436
+ if err != nil {
437
+ return fmt .Errorf ("failed to update configuration for client %s: %w" , clientToRemove .Name , err )
438
+ }
439
+
440
+ return nil
441
+ }
0 commit comments