1
- import { type } from "node:os" ;
2
-
3
1
// Barebones Teleport resource definitions, ensuring type safety and autocomplete
4
2
type GenericResource = {
3
+ kind ?: string ;
5
4
metadata : {
6
5
name : string ;
7
6
description : string ;
8
7
} ;
9
8
} ;
10
9
11
- type User = object & GenericResource ;
10
+ type Node = {
11
+ spec : {
12
+ hostname : string ;
13
+ } ;
14
+ } & GenericResource ;
12
15
13
- type Role = object & GenericResource ;
16
+ enum AccessRequestState {
17
+ "NONE" ,
18
+ "PENDING" ,
19
+ "DENIED" ,
20
+ "APPROVED" ,
21
+ }
22
+
23
+ type AccessRequest = {
24
+ spec : {
25
+ user : string ;
26
+ roles : string [ ] ;
27
+ request_reason : string ;
28
+ state : number ;
29
+ } ;
30
+ } & GenericResource ;
14
31
15
- type App = object & GenericResource ;
32
+ type User = {
33
+ spec : {
34
+ created_by : {
35
+ time : string ;
36
+ user : {
37
+ name : string ;
38
+ } ;
39
+ } ;
40
+ status : {
41
+ is_locked : boolean ;
42
+ lock_expires : string ;
43
+ } ;
44
+ } ;
45
+ } & GenericResource ;
16
46
17
- type Db = object & GenericResource ;
47
+ type Lock = {
48
+ spec : {
49
+ target : {
50
+ user : string ;
51
+ } ;
52
+ created_by : string ;
53
+ expires : string ;
54
+ } ;
55
+ } & GenericResource ;
18
56
19
- type AccessRequest = object & GenericResource ;
57
+ type Role = object & GenericResource ;
20
58
21
59
type Token = object & GenericResource ;
22
60
23
61
type Bot = object & GenericResource ;
24
62
25
- type WindowsDesktop = object & GenericResource ;
26
-
27
63
type ACL = object & GenericResource ;
28
64
29
65
type Alert = object & GenericResource ;
30
66
31
- type Device = object & GenericResource ;
32
-
33
- type Connector = object & GenericResource ;
34
-
35
67
type Namespace = object & GenericResource ;
36
68
37
69
type Cluster = {
38
70
kube_cluster_name : string ;
39
71
} ;
40
72
41
- const teleportAccountsGenerator : Fig . Generator = {
42
- script : "tctl get users --format json" ,
43
- postProcess : function ( out ) {
44
- const users = JSON . parse ( out ) ;
45
-
46
- return users . map ( ( user : User ) => {
47
- return {
48
- name : user . metadata . name ,
49
- description : user . metadata . description ,
50
- } ;
51
- } ) ;
52
- } ,
73
+ const commaQueryTerm = ( curr ) => {
74
+ return curr . split ( "," ) . pop ( ) ;
53
75
} ;
54
76
55
- const teleportKubernetesClustersGenerator : Fig . Generator = {
56
- script : "tsh kube ls --format json" ,
57
- postProcess : function ( out ) {
58
- const clusters = JSON . parse ( out ) ;
77
+ // Prefix is used as sometimes Teleport wants the "type" with the request, e.g. tctl get user/USERNAME (user is the prefix here)
78
+ const resourcePostProcesserBuilder = ( prefix : string = "" ) => {
79
+ return ( out : string , tokens : string [ ] ) : Fig . Suggestion [ ] => {
80
+ const resources = JSON . parse ( out ) ;
59
81
60
- return clusters . map ( ( cluster : Cluster ) => {
61
- return {
62
- name : cluster . kube_cluster_name ,
63
- description : "Kubernetes cluster connected to Teleport" ,
64
- } ;
65
- } ) ;
66
- } ,
67
- } ;
82
+ const postProcesser = resources
83
+ . map ( ( resource : GenericResource ) : Fig . Suggestion => {
84
+ if ( resource . kind === "node" ) {
85
+ const node = resource as Node ;
68
86
69
- const commaQueryTerm = ( curr ) => {
70
- if ( curr . includes ( "," ) ) {
71
- return curr . slice ( curr . lastIndexOf ( "," ) + 1 ) ;
72
- } else {
73
- return curr ;
74
- }
75
- } ;
87
+ return {
88
+ name : `${ prefix } ${ node . spec . hostname } ` ,
76
89
77
- const filterRoles = ( currentRoles : string , allRoles : Role [ ] ) => {
78
- let currentRolesString = currentRoles ;
90
+ // If there is a resource prefix, we do not need to use the UID (name) because its already unique
91
+ insertValue : prefix
92
+ ? `${ prefix } ${ node . spec . hostname } `
93
+ : node . metadata . name ,
79
94
80
- if ( currentRoles . includes ( "=" ) ) {
81
- currentRolesString = currentRoles . split ( "=" ) [ 1 ] ;
82
- }
95
+ description : "Inserts UUID: " + node . metadata . name ,
96
+ priority : 65 ,
97
+ } ;
98
+ }
83
99
84
- const filterable = currentRolesString . split ( "," ) ;
100
+ if ( resource . kind === "lock" ) {
101
+ const lock = resource as Lock ;
85
102
86
- return allRoles . filter ( ( role : Role ) => {
87
- return ! filterable . includes ( role . metadata . name ) ;
88
- } ) ;
103
+ return {
104
+ name : `${ resource . kind } /${ lock . metadata . name } ` ,
105
+ description : "Created by: " + lock . spec . created_by ,
106
+ priority : 65 ,
107
+ } ;
108
+ }
109
+
110
+ if ( resource . kind === "access_request" ) {
111
+ const request = resource as AccessRequest ;
112
+
113
+ return {
114
+ name : `${ prefix } ${ AccessRequestState [ request . spec . state ] } ${
115
+ request . spec . user
116
+ } `,
117
+ insertValue : request . metadata . name ,
118
+ description : `Requests: ${ request . spec . roles . join ( ", " ) } ` ,
119
+ priority : 76 ,
120
+ } ;
121
+ }
122
+
123
+ if ( resource . kind === "user" ) {
124
+ const user = resource as User ;
125
+ const locked = user . spec . status . is_locked ;
126
+ const lockedExpires = user . spec . status . lock_expires ;
127
+
128
+ let description = locked
129
+ ? `User locked until ${ lockedExpires } `
130
+ : user . metadata . description ;
131
+
132
+ if ( ! description ) {
133
+ const created = new Date (
134
+ user . spec . created_by . time
135
+ ) . toLocaleDateString ( ) ;
136
+ const creator = user . spec . created_by . user . name ;
137
+
138
+ description = `${ creator } created this user on ${ created } ` ;
139
+ }
140
+
141
+ return {
142
+ name : `${ prefix } ${ user . metadata . name } ` ,
143
+ icon : locked
144
+ ? "fig://icon?type=box&=FF0000&badge=🚫"
145
+ : "fig://icon?type=box" ,
146
+ description,
147
+ priority : 65 ,
148
+ } ;
149
+ }
150
+
151
+ return {
152
+ name : `${ prefix } ${ resource . metadata . name } ` ,
153
+ description : resource . metadata . description ,
154
+ priority : 65 ,
155
+ } ;
156
+ } )
157
+ . filter ( ( suggestion : Fig . Suggestion ) => {
158
+ // The last token always contains the resources
159
+ const lastToken = tokens [ tokens . length - 1 ] ;
160
+
161
+ // We remove the resources that we are already listing, this wont impact single resource selection options
162
+ return ! lastToken . includes ( suggestion . name . toString ( ) ) ;
163
+ } ) ;
164
+
165
+ return postProcesser ;
166
+ } ;
89
167
} ;
90
168
91
- const teleportRolesGenerator : Fig . Generator = {
92
- script : "tctl get roles --format json" ,
93
- getQueryTerm : commaQueryTerm ,
94
- postProcess : function ( out , tokens ) {
95
- const roles = JSON . parse ( out ) ;
169
+ const tctlGetGenerator = (
170
+ resource : string ,
171
+ canBeMultiple : boolean = false
172
+ ) : Fig . Generator => {
173
+ return {
174
+ script : `tctl get ${ resource } --format json` ,
175
+ getQueryTerm : canBeMultiple ? commaQueryTerm : undefined ,
176
+ postProcess : resourcePostProcesserBuilder ( ) ,
177
+ } ;
178
+ } ;
96
179
97
- const filteredRoles = filterRoles ( tokens [ tokens . length - 1 ] , roles ) ;
180
+ const tshListGenerator = ( resource : string ) : Fig . Generator => {
181
+ return {
182
+ script : `tsh ${ resource } ls --format json` ,
183
+ postProcess : resourcePostProcesserBuilder ( ) ,
184
+ } ;
185
+ } ;
98
186
99
- return filteredRoles . map ( ( role : Role ) => {
100
- return {
101
- name : role . metadata . name ,
102
- description : role . metadata . description ,
103
- } ;
104
- } ) ;
187
+ const teleportGenerators : Record < string , Fig . Generator > = {
188
+ yamlFiles : {
189
+ template : "filepaths" ,
190
+ // Only show YAML files and directories
191
+ filterTemplateSuggestions : function ( paths ) {
192
+ return paths . filter (
193
+ ( file ) =>
194
+ file . name . endsWith ( "/" ) ||
195
+ file . name . endsWith ( ".yaml" ) ||
196
+ file . name . endsWith ( ".yml" )
197
+ ) ;
198
+ } ,
105
199
} ,
200
+
201
+ // Shorthand suggestion generators
202
+ role : tctlGetGenerator ( "roles" ) ,
203
+ roles : tctlGetGenerator ( "roles" , true ) ,
204
+ user : tctlGetGenerator ( "user" ) ,
205
+ windows_desktop : tctlGetGenerator ( "windows_desktop" ) ,
206
+ node : tctlGetGenerator ( "node" ) ,
207
+ device : tctlGetGenerator ( "device" ) ,
208
+ connector : tctlGetGenerator ( "connector" ) ,
209
+ kube : tshListGenerator ( "kube" ) ,
210
+ apps : tshListGenerator ( "apps" ) ,
211
+ db : tshListGenerator ( "db" ) ,
212
+ request : tshListGenerator ( "request" ) ,
213
+ tokens : tshListGenerator ( "tokens" ) ,
106
214
} ;
107
215
108
- const teleportAppGenerator : Fig . Generator = {
109
- script : "tsh apps ls --format json" ,
110
- postProcess : function ( out ) {
111
- const apps = JSON . parse ( out ) ;
112
- return apps . map ( ( app : App ) => {
113
- return {
114
- name : app . metadata . name ,
115
- description : app . metadata . description ,
116
- } ;
117
- } ) ;
216
+ const teleportOptions : Record < string , Fig . Option > = {
217
+ ttl : {
218
+ name : "--ttl" ,
219
+ description : "Set the time to live, default is 1h0m0s, maximum is 48h0m0s" ,
220
+ args : {
221
+ name : "10h10m10s" ,
222
+ description : "Relative duration like 5s, can be chained like 1h10m10s" ,
223
+ } ,
118
224
} ,
119
- } ;
120
225
121
- const teleportDatabaseGenerator : Fig . Generator = {
122
- script : "tsh db ls --format json" ,
123
- postProcess : function ( out ) {
124
- const dbs = JSON . parse ( out ) ;
125
- return dbs . map ( ( db : Db ) => {
126
- return {
127
- name : db . metadata . name ,
128
- description : db . metadata . description ,
129
- } ;
130
- } ) ;
226
+ format : {
227
+ name : "--format" ,
228
+ description : "Output format. One of: [text, json, yaml]" ,
229
+ args : {
230
+ name : "format" ,
231
+ suggestions : [ "text" , "json" , "yaml" ] ,
232
+ default : "yaml" ,
233
+ } ,
131
234
} ,
132
- } ;
133
235
134
- const teleportRequestGenerator : Fig . Generator = {
135
- script : "tctl request ls --format json" ,
136
- postProcess : function ( out ) {
137
- const requests = JSON . parse ( out ) ;
138
- return requests . map ( ( request : AccessRequest ) => {
139
- return {
140
- name : request . metadata . name ,
141
- description : request . metadata . description ,
142
- } ;
143
- } ) ;
236
+ labels : {
237
+ name : "--labels" ,
238
+ description : "Which labels to add to the resource" ,
239
+ args : {
240
+ name : "label1=value1,label2=value2" ,
241
+ } ,
144
242
} ,
145
- } ;
146
243
147
- const teleportTokenGenerator : Fig . Generator = {
148
- script : "tctl tokens ls --format json" ,
149
- postProcess : function ( out ) {
150
- const tokens = JSON . parse ( out ) ;
151
- return tokens . map ( ( token : Token ) => {
152
- return {
153
- name : token . metadata . name ,
154
- description : token . metadata . description ,
155
- } ;
156
- } ) ;
244
+ reason : {
245
+ name : "--reason" ,
246
+ description : "Optional reason message" ,
247
+ insertValue : "--reason '{cursor}'" ,
248
+ args : {
249
+ name : "reason" ,
250
+ } ,
157
251
} ,
158
- } ;
159
252
160
- const teleportWindowsDesktopGenerator : Fig . Generator = {
161
- script : "tctl get windows_desktop --format json" ,
162
- postProcess : function ( out ) {
163
- const desktops = JSON . parse ( out ) ;
164
- return desktops . map ( ( desktop : WindowsDesktop ) => {
165
- return {
166
- name : desktop . metadata . name ,
167
- description : desktop . metadata . description ,
168
- } ;
169
- } ) ;
253
+ roles : {
254
+ name : "--roles" ,
255
+ description : "Comma seperated list of roles" ,
256
+ args : {
257
+ name : "role1,role2" ,
258
+ generators : teleportGenerators . roles ,
259
+ } ,
170
260
} ,
171
- } ;
172
261
173
- const teleportFormatOption : Fig . Option = {
174
- name : "--format" ,
175
- description : "Output format. One of: [text, json, yaml]" ,
176
- args : {
177
- name : "format" ,
178
- suggestions : [ "text" , "json" , "yaml" ] ,
179
- default : "text" ,
262
+ logins : {
263
+ name : "--logins" ,
264
+ description : "List of allowed SSH logins" ,
265
+ args : {
266
+ name : "login1,login2" ,
267
+ } ,
180
268
} ,
181
269
} ;
182
270
271
+ const filterRoles = ( currentRoles : string , allRoles : Role [ ] ) => {
272
+ let currentRolesString = currentRoles ;
273
+
274
+ if ( currentRoles . includes ( "=" ) ) {
275
+ currentRolesString = currentRoles . split ( "=" ) [ 1 ] ;
276
+ }
277
+
278
+ const filterable = currentRolesString . split ( "," ) ;
279
+
280
+ return allRoles . filter ( ( role : Role ) => {
281
+ return ! filterable . includes ( role . metadata . name ) ;
282
+ } ) ;
283
+ } ;
284
+
183
285
const teleportBotsGenerator : Fig . Generator = {
184
286
script : "tctl bots ls --format json" ,
185
287
postProcess : function ( out ) {
@@ -219,37 +321,11 @@ const teleportAlertGenerator: Fig.Generator = {
219
321
} ,
220
322
} ;
221
323
222
- const teleportDeviceGenerator : Fig . Generator = {
223
- script : "tctl get device --format json" ,
224
- postProcess : function ( out ) {
225
- const devices = JSON . parse ( out ) ;
226
- return devices . map ( ( device : Device ) => {
227
- return {
228
- name : device . metadata . name ,
229
- description : device . metadata . description ,
230
- } ;
231
- } ) ;
232
- } ,
233
- } ;
234
-
235
- const teleportSAMLConnectorGenerator : Fig . Generator = {
236
- script : "tctl get connector --format json" ,
237
- postProcess : function ( out ) {
238
- const connectors = JSON . parse ( out ) ;
239
- return connectors . map ( ( connector : Connector ) => {
240
- return {
241
- name : connector . metadata . name ,
242
- description : connector . metadata . description ,
243
- } ;
244
- } ) ;
245
- } ,
246
- } ;
247
-
248
324
const teleportGetResourcesGenerator : Fig . Generator = {
249
325
trigger : ( current , old ) => {
250
- return true ;
326
+ return current . lastIndexOf ( "/" ) > old . lastIndexOf ( "/" ) ;
251
327
} ,
252
- custom : async ( tokens , executeShellCommand ) => {
328
+ custom : async ( tokens , executeShellCommand ) : Promise < Fig . Suggestion [ ] > => {
253
329
const standardSuggestions = [
254
330
"user" ,
255
331
"role" ,
@@ -264,10 +340,12 @@ const teleportGetResourcesGenerator: Fig.Generator = {
264
340
"lock" ,
265
341
"all" ,
266
342
] ;
343
+
267
344
const respondSuggestions = standardSuggestions . map ( ( suggestion ) => {
268
345
return {
269
346
name : suggestion ,
270
347
description : "Get a " + suggestion ,
348
+ priority : 100 ,
271
349
} ;
272
350
} ) ;
273
351
@@ -281,52 +359,68 @@ const teleportGetResourcesGenerator: Fig.Generator = {
281
359
. find ( ( token ) => standardSuggestions . includes ( token . split ( "/" ) [ 0 ] ) )
282
360
. split ( "/" ) [ 0 ] ;
283
361
362
+ // Only show suggestions for resources that are supported by tctl
284
363
if ( standardSuggestions . find ( ( sug ) => sug === resource ) == undefined )
285
364
return respondSuggestions ;
365
+
286
366
if ( [ "cluster_auth_preference" , "all" ] . includes ( resource ) ) return [ ] ; // This is what tctl expects
287
367
288
368
const resources = await executeShellCommand (
289
369
`tctl get ${ resource } --format json`
290
370
) ;
371
+
291
372
const parsedResources = JSON . parse ( resources ) ;
292
373
293
- return parsedResources . map ( ( parsedResource : GenericResource ) => {
294
- return {
295
- name : `${ resource } /${ parsedResource . metadata . name } ` ,
296
- } ;
297
- } ) ;
374
+ let parsedLocks : Lock [ ] = [ ] ;
375
+
376
+ if ( [ "lock" , "user" ] . includes ( resource ) ) {
377
+ const locks = await executeShellCommand ( `tctl get locks --format json` ) ;
378
+ parsedLocks = JSON . parse ( locks ) ;
379
+ }
380
+
381
+ const postProcessResource = resourcePostProcesserBuilder ( `${ resource } /` ) ;
382
+
383
+ if ( resource === "user" ) {
384
+ const users = parsedResources as User [ ] ;
385
+
386
+ users . forEach ( ( user ) => {
387
+ parsedLocks . find ( ( lock ) => {
388
+ if ( lock . spec . target . user === user . metadata . name ) {
389
+ user . spec . status . is_locked = true ;
390
+ user . spec . status . lock_expires = lock . spec . expires ;
391
+ }
392
+ } ) ;
393
+ } ) ;
394
+
395
+ return postProcessResource ( JSON . stringify ( users ) , tokens ) ;
396
+ }
397
+
398
+ return postProcessResource ( JSON . stringify ( parsedResources ) , tokens ) ;
298
399
}
299
400
300
401
return respondSuggestions ;
301
402
} ,
302
403
} ;
303
404
304
- /* tctl lock --help
305
- --user Name of a Teleport user to disable.
306
- --role Name of a Teleport role to disable.
307
- --login Name of a local UNIX user to disable.
308
- --mfa-device UUID of a user MFA device to disable.
309
- --windows-desktop Name of a Windows desktop to disable.
310
- --access-request UUID of an access request to disable.
311
- --device UUID of a trusted device to disable.
312
- --message Message to display to locked-out users.
313
- --expires Time point (RFC3339) when the lock expires.
314
- --ttl Time duration after which the lock expires.
315
- --server-id UUID of a Teleport server to disable.
316
- */
317
-
318
405
const completionSpec : Fig . Spec = {
319
406
name : "tctl" ,
320
407
description : "Admin tool for the Teleport Access Platform" ,
408
+ args : { } ,
409
+ requiresSubcommand : true ,
321
410
subcommands : [
322
411
/* tctl help */
323
412
{
324
413
name : "help" ,
325
414
description : "Show help" ,
415
+ priority : 100 ,
326
416
} ,
327
417
/* tctl users */
328
418
{
329
419
name : "users" ,
420
+ description : "Manage user accounts" ,
421
+ requiresSubcommand : true ,
422
+ args : { } ,
423
+ priority : 100 ,
330
424
subcommands : [
331
425
{
332
426
name : "add" ,
@@ -336,69 +430,86 @@ const completionSpec: Fig.Spec = {
336
430
description : "Teleport user account name" ,
337
431
} ,
338
432
options : [
339
- {
340
- name : "--logins" ,
341
- description : "List of allowed SSH logins for the new user" ,
342
- } ,
433
+ teleportOptions . ttl ,
434
+ teleportOptions . roles ,
435
+ teleportOptions . logins ,
343
436
{
344
437
name : "--windows-logins" ,
345
438
description : "List of allowed Windows logins for the new user" ,
439
+ args : {
440
+ name : "login1,login2" ,
441
+ } ,
346
442
} ,
347
443
{
348
444
name : "--kubernetes-users" ,
349
445
description : "List of allowed Kubernetes users for the new user" ,
446
+ args : {
447
+ name : "value1,value2" ,
448
+ } ,
350
449
} ,
351
450
{
352
451
name : "--kubernetes-groups" ,
353
452
description : "List of allowed Kubernetes groups for the new user" ,
453
+ args : {
454
+ name : "group1,group2" ,
455
+ } ,
354
456
} ,
355
457
{
356
458
name : "--db-users" ,
357
459
description : "List of allowed database users for the new user" ,
460
+ args : {
461
+ name : "user1,user2" ,
462
+ } ,
358
463
} ,
359
464
{
360
465
name : "--db-names" ,
361
466
description : "List of allowed database names for the new user" ,
467
+ args : {
468
+ name : "value1,value2" ,
469
+ } ,
362
470
} ,
363
471
{
364
472
name : "--db-roles" ,
365
473
description :
366
474
"List of database roles for automatic database user provisioning" ,
475
+ args : {
476
+ name : "name1,name2" ,
477
+ } ,
367
478
} ,
368
479
{
369
480
name : "--aws-role-arns" ,
370
481
description : "List of allowed AWS role ARNs for the new user" ,
482
+ args : {
483
+ name : "value1,value2" ,
484
+ } ,
371
485
} ,
372
486
{
373
487
name : "--azure-identities" ,
374
488
description : "List of allowed Azure identities for the new user" ,
489
+ args : {
490
+ name : "identity1,identity2" ,
491
+ } ,
375
492
} ,
376
493
{
377
494
name : "--gcp-service-accounts" ,
378
495
description :
379
496
"List of allowed GCP service accounts for the new user" ,
497
+ args : {
498
+ name : "account1,account2" ,
499
+ } ,
380
500
} ,
381
501
{
382
502
name : "--host-user-uid" ,
383
503
description : "UID for auto provisioned host users to use" ,
504
+ args : {
505
+ name : "user-id" ,
506
+ } ,
384
507
} ,
385
508
{
386
509
name : "--host-user-gid" ,
387
510
description : "GID for auto provisioned host users to use" ,
388
- } ,
389
- {
390
- name : "--ttl" ,
391
- description :
392
- "Set expiration time for token, default is 1h0m0s, maximum is 48h0m0s" ,
393
- } ,
394
- {
395
- name : "--roles" ,
396
- description :
397
- "List of roles for the new user to assume. Comma seperated" ,
398
- isRequired : true ,
399
- isRepeatable : true ,
400
511
args : {
401
- generators : teleportRolesGenerator ,
512
+ name : "group-id" ,
402
513
} ,
403
514
} ,
404
515
] ,
@@ -410,81 +521,119 @@ const completionSpec: Fig.Spec = {
410
521
{
411
522
name : "--set-roles" ,
412
523
description :
413
- "List of roles for the user to assume, replaces current roles. Comma seperated " ,
524
+ "List of roles for the user to assume, replaces current roles" ,
414
525
args : {
415
- generators : teleportRolesGenerator ,
526
+ name : "role1,role2" ,
527
+ generators : teleportGenerators . roles ,
416
528
} ,
417
529
} ,
418
530
{
419
531
name : "--set-logins" ,
420
532
description :
421
533
"List of allowed SSH logins for the user, replaces current logins" ,
534
+ args : {
535
+ name : "value1,value2" ,
536
+ } ,
422
537
} ,
423
538
{
424
539
name : "--set-windows-logins" ,
425
540
description :
426
541
"List of allowed Windows logins for the user, replaces current Windows logins" ,
542
+ args : {
543
+ name : "value1,value2" ,
544
+ } ,
427
545
} ,
428
546
{
429
547
name : "--set-kubernetes-users" ,
430
548
description :
431
549
"List of allowed Kubernetes users for the user, replaces current Kubernetes users" ,
550
+ args : {
551
+ name : "value1,value2" ,
552
+ } ,
432
553
} ,
433
554
{
434
555
name : "--set-kubernetes-groups" ,
435
556
description :
436
557
"List of allowed Kubernetes groups for the user, replaces current Kubernetes groups" ,
558
+ args : {
559
+ name : "value1,value2" ,
560
+ } ,
437
561
} ,
438
562
{
439
563
name : "--set-db-users" ,
440
564
description :
441
565
"List of allowed database users for the user, replaces current database users" ,
566
+ args : {
567
+ name : "value1,value2" ,
568
+ } ,
442
569
} ,
443
570
{
444
571
name : "--set-db-names" ,
445
572
description :
446
573
"List of allowed database names for the user, replaces current database names" ,
574
+ args : {
575
+ name : "value1,value2" ,
576
+ } ,
447
577
} ,
448
578
{
449
579
name : "--set-db-roles" ,
450
580
description :
451
581
"List of allowed database roles for automatic database user provisioning, replaces current database roles" ,
582
+ args : {
583
+ name : "value1,value2" ,
584
+ } ,
452
585
} ,
453
586
{
454
587
name : "--set-aws-role-arns" ,
455
588
description :
456
589
"List of allowed AWS role ARNs for the user, replaces current AWS role ARNs" ,
590
+ args : {
591
+ name : "value1,value2" ,
592
+ } ,
457
593
} ,
458
594
{
459
595
name : "--set-azure-identities" ,
460
596
description :
461
597
"List of allowed Azure identities for the user, replaces current Azure identities" ,
598
+ args : {
599
+ name : "value1,value2" ,
600
+ } ,
462
601
} ,
463
602
{
464
603
name : "--set-gcp-service-accounts" ,
465
604
description :
466
605
"List of allowed GCP service accounts for the user, replaces current service accounts" ,
606
+ args : {
607
+ name : "value1,value2" ,
608
+ } ,
467
609
} ,
468
610
{
469
611
name : "--set-host-user-uid" ,
470
612
description :
471
613
"UID for auto provisioned host users to use. Value can be reset by providing an empty string" ,
614
+ args : {
615
+ name : "user-id" ,
616
+ } ,
472
617
} ,
473
618
{
474
619
name : "--set-host-user-gid" ,
475
620
description :
476
621
"GID for auto provisioned host users to use. Value can be reset by providing an empty string" ,
622
+ args : {
623
+ name : "group-id" ,
624
+ } ,
477
625
} ,
478
626
] ,
479
627
args : {
480
628
name : "account" ,
481
629
description : "Teleport user account name" ,
482
- generators : teleportAccountsGenerator ,
630
+ generators : teleportGenerators . user ,
483
631
} ,
484
632
} ,
485
633
{
486
634
name : "ls" ,
487
635
description : "Lists all user accounts" ,
636
+ options : [ teleportOptions . format ] ,
488
637
} ,
489
638
{
490
639
name : "rm" ,
@@ -493,7 +642,7 @@ const completionSpec: Fig.Spec = {
493
642
name : "account" ,
494
643
description : "Teleport user account name" ,
495
644
isVariadic : true ,
496
- generators : teleportAccountsGenerator ,
645
+ generators : teleportGenerators . user ,
497
646
} ,
498
647
} ,
499
648
{
@@ -503,25 +652,30 @@ const completionSpec: Fig.Spec = {
503
652
args : {
504
653
name : "account" ,
505
654
description : "Teleport user account name" ,
506
- generators : teleportAccountsGenerator ,
655
+ generators : teleportGenerators . user ,
507
656
} ,
508
657
} ,
509
658
] ,
510
659
} ,
511
660
/* tctl nodes */
512
661
{
513
662
name : "nodes" ,
663
+ priority : 100 ,
514
664
description : "Issue invites for other nodes to join the cluster" ,
665
+ requiresSubcommand : true ,
515
666
subcommands : [
516
667
{
517
668
name : "add" ,
518
669
description : "Generate a node invitation token" ,
670
+ args : { } ,
519
671
options : [
672
+ teleportOptions . ttl ,
520
673
{
521
674
name : "--roles" ,
522
675
description :
523
676
"Comma-separated list of roles for the new node to assume" ,
524
677
args : {
678
+ name : "role1,role2" ,
525
679
generators : {
526
680
getQueryTerm : commaQueryTerm ,
527
681
trigger : ( current , old ) => {
@@ -552,17 +706,13 @@ const completionSpec: Fig.Spec = {
552
706
} ,
553
707
} ,
554
708
} ,
555
- {
556
- name : "--ttl" ,
557
- description :
558
- "Time to live for a generated token, default is 0h30m0s, maximum is 48h0m0s" ,
559
- } ,
560
709
] ,
561
710
} ,
562
711
{
563
712
name : "ls" ,
564
713
description : "List all active SSH nodes within the cluster" ,
565
714
options : [
715
+ teleportOptions . format ,
566
716
{
567
717
name : "--namespace" ,
568
718
description : "Namespace of the nodes" ,
@@ -592,14 +742,18 @@ const completionSpec: Fig.Spec = {
592
742
/* tctl tokens */
593
743
{
594
744
name : "tokens" ,
745
+ priority : 100 ,
595
746
description : "Manage invitation tokens" ,
747
+ requiresSubcommand : true ,
748
+ args : { } ,
596
749
subcommands : [
597
750
{
598
751
name : "add" ,
599
752
description : "Create a invitation token" ,
600
753
args : { } ,
601
754
options : [
602
- teleportFormatOption ,
755
+ teleportOptions . format ,
756
+ teleportOptions . ttl ,
603
757
{
604
758
name : "--type" ,
605
759
description : "Type(s) of token to add" ,
@@ -699,14 +853,6 @@ const completionSpec: Fig.Spec = {
699
853
name : "label1=value1,label2=value2" ,
700
854
} ,
701
855
} ,
702
- {
703
- name : "--ttl" ,
704
- description :
705
- "Set expiration time for token, default is 30 minutes" ,
706
- args : {
707
- name : "30m" ,
708
- } ,
709
- } ,
710
856
{
711
857
name : "--app-name" ,
712
858
description : "Name of the application to add" ,
@@ -779,7 +925,7 @@ const completionSpec: Fig.Spec = {
779
925
{
780
926
name : "ls" ,
781
927
description : "List node and user invitation tokens" ,
782
- options : [ teleportFormatOption ] ,
928
+ options : [ teleportOptions . format ] ,
783
929
} ,
784
930
] ,
785
931
} ,
@@ -788,6 +934,7 @@ const completionSpec: Fig.Spec = {
788
934
name : "auth" ,
789
935
description :
790
936
"Operations with user and host certificate authorities (CAs)" ,
937
+ priority : 100 ,
791
938
args : { } ,
792
939
subcommands : [
793
940
{
@@ -801,6 +948,9 @@ const completionSpec: Fig.Spec = {
801
948
{
802
949
name : "--fingerprint" ,
803
950
description : "Filter authority by fingerprint" ,
951
+ args : {
952
+ name : "fingerprint" ,
953
+ } ,
804
954
} ,
805
955
{
806
956
name : "--compat" ,
@@ -841,10 +991,11 @@ const completionSpec: Fig.Spec = {
841
991
{
842
992
name : "--user" ,
843
993
description : "Teleport user name" ,
994
+ priority : 100 ,
844
995
isRequired : true ,
845
996
args : {
846
997
name : "user" ,
847
- generators : teleportAccountsGenerator ,
998
+ generators : teleportGenerators . user ,
848
999
} ,
849
1000
} ,
850
1001
{
@@ -857,6 +1008,7 @@ const completionSpec: Fig.Spec = {
857
1008
{
858
1009
name : [ "--out" , "-o" ] ,
859
1010
description : "Identity output" ,
1011
+ priority : 99 ,
860
1012
isRequired : true ,
861
1013
args : {
862
1014
name : "out" ,
@@ -873,11 +1025,8 @@ const completionSpec: Fig.Spec = {
873
1025
} ,
874
1026
} ,
875
1027
{
876
- name : "-- ttl" ,
1028
+ ... teleportOptions . ttl ,
877
1029
description : "TTL (time to live) for the generated certificate" ,
878
- args : {
879
- name : "ttl" ,
880
- } ,
881
1030
} ,
882
1031
{
883
1032
name : "--compat" ,
@@ -920,66 +1069,95 @@ const completionSpec: Fig.Spec = {
920
1069
'Kubernetes cluster to generate identity file for when --format is set to "kubernetes"' ,
921
1070
args : {
922
1071
name : "name" ,
923
- generators : teleportKubernetesClustersGenerator ,
1072
+ generators : {
1073
+ ...teleportGenerators . kube ,
1074
+ postProcess : function ( out ) {
1075
+ const clusters = JSON . parse ( out ) ;
1076
+
1077
+ return clusters . map ( ( cluster : Cluster ) => {
1078
+ return {
1079
+ name : cluster . kube_cluster_name ,
1080
+ description : "Kubernetes cluster connected to Teleport" ,
1081
+ } ;
1082
+ } ) ;
1083
+ } ,
1084
+ } ,
924
1085
} ,
925
1086
} ,
926
1087
{
927
1088
name : "--app-name" ,
928
1089
description :
929
1090
'Application to generate identity file for. Mutually exclusive with "--db-service"' ,
1091
+ exclusiveOn : [ "--db-service" ] ,
930
1092
args : {
931
1093
name : "name" ,
932
- generators : teleportAppGenerator ,
1094
+ generators : teleportGenerators . apps ,
933
1095
} ,
934
1096
} ,
935
1097
{
936
1098
name : "--db-service" ,
937
1099
description :
938
1100
'Database to generate identity file for. Mutually exclusive with "--app-name"' ,
1101
+ exclusiveOn : [ "--app-name" ] ,
939
1102
args : {
940
1103
name : "service" ,
941
- generators : teleportDatabaseGenerator ,
1104
+ generators : teleportGenerators . db ,
942
1105
} ,
943
1106
} ,
944
1107
{
945
1108
name : "--db-user" ,
946
1109
description :
947
1110
'Database user placed on the identity file. Only used when "--db-service" is set' ,
1111
+ dependsOn : [ "--db-service" ] ,
1112
+ args : {
1113
+ name : "user" ,
1114
+ } ,
948
1115
} ,
949
1116
{
950
1117
name : "--db-name" ,
951
1118
description :
952
1119
'Database name placed on the identity file. Only used when "--db-service" is set' ,
1120
+ dependsOn : [ "--db-service" ] ,
1121
+ args : {
1122
+ name : "name" ,
1123
+ } ,
953
1124
} ,
954
1125
{
955
1126
name : "--windows-user" ,
956
1127
description :
957
1128
'Window user placed on the identity file. Only used when --format is set to "windows"' ,
1129
+ args : {
1130
+ name : "user" ,
1131
+ } ,
958
1132
} ,
959
1133
{
960
1134
name : "--windows-domain" ,
961
1135
description :
962
1136
'Active Directory domain for which this cert is valid. Only used when --format is set to "windows"' ,
1137
+ args : {
1138
+ name : "domain" ,
1139
+ } ,
963
1140
} ,
964
1141
{
965
1142
name : "--windows-sid" ,
966
1143
description :
967
1144
'Optional Security Identifier to embed in the certificate. Only used when --format is set to "windows"' ,
1145
+ args : {
1146
+ name : "security-id" ,
1147
+ } ,
968
1148
} ,
969
1149
] ,
970
1150
} ,
971
1151
{
972
1152
name : "rotate" ,
973
1153
description : "Rotate certificate authorities in the cluster" ,
1154
+ args : { } ,
1155
+ isDangerous : true ,
974
1156
options : [
975
1157
{
1158
+ ...teleportOptions . ttl ,
976
1159
name : "--grace-period" ,
977
- description :
978
- "Grace period keeps previous certificate authorities signatures valid, if set to 0 will force users to re-login and nodes to re-register" ,
979
- args : {
980
- name : "duration" ,
981
- description : "Relative duration like 5s, 2m, or 3h" ,
982
- } ,
1160
+ description : "Grace period keeps previous CA valid" ,
983
1161
} ,
984
1162
{
985
1163
name : "--manual" ,
@@ -1025,12 +1203,13 @@ const completionSpec: Fig.Spec = {
1025
1203
{
1026
1204
name : "ls" ,
1027
1205
description : "List connected auth servers" ,
1028
- options : [ teleportFormatOption ] ,
1206
+ options : [ teleportOptions . format ] ,
1029
1207
} ,
1030
1208
{
1031
1209
name : "crl" ,
1032
1210
description :
1033
1211
"Export empty certificate revocation list (CRL) for certificate authorities" ,
1212
+ args : { } ,
1034
1213
options : [
1035
1214
{
1036
1215
name : "--type" ,
@@ -1050,13 +1229,14 @@ const completionSpec: Fig.Spec = {
1050
1229
{
1051
1230
name : "get" ,
1052
1231
description : "Get a resource" ,
1232
+ priority : 100 ,
1053
1233
args : {
1054
- name : "resource " ,
1055
- description : "Resource to get" ,
1234
+ name : "type/name " ,
1235
+ description : "Resource to get (e.g. user/bob) " ,
1056
1236
generators : teleportGetResourcesGenerator ,
1057
1237
} ,
1058
1238
options : [
1059
- teleportFormatOption ,
1239
+ teleportOptions . format ,
1060
1240
{
1061
1241
name : "--with-secrets" ,
1062
1242
description :
@@ -1072,11 +1252,13 @@ const completionSpec: Fig.Spec = {
1072
1252
{
1073
1253
name : "status" ,
1074
1254
description : "Report cluster status" ,
1255
+ priority : 100 ,
1075
1256
} ,
1076
1257
/* tctl top */
1077
1258
{
1078
1259
name : "top" ,
1079
1260
description : "Report cluster status" ,
1261
+ priority : 100 ,
1080
1262
args : [
1081
1263
{
1082
1264
name : "diag-address" ,
@@ -1093,27 +1275,30 @@ const completionSpec: Fig.Spec = {
1093
1275
name : [ "requests" , "request" ] ,
1094
1276
description : "Manage access requests" ,
1095
1277
args : { } ,
1278
+ priority : 100 ,
1096
1279
subcommands : [
1097
1280
{
1098
1281
name : "ls" ,
1099
1282
description : "Show active access requests" ,
1283
+ options : [ teleportOptions . format ] ,
1100
1284
} ,
1101
1285
{
1102
1286
name : "get" ,
1103
1287
description : "Show access request details" ,
1104
1288
args : {
1105
1289
name : "request" ,
1106
1290
description : "Access request ID" ,
1107
- generators : teleportRequestGenerator ,
1291
+ generators : teleportGenerators . request ,
1108
1292
} ,
1293
+ options : [ teleportOptions . format ] ,
1109
1294
} ,
1110
1295
{
1111
1296
name : "approve" ,
1112
1297
description : "Approve pending access request" ,
1113
1298
args : {
1114
1299
name : "request" ,
1115
1300
description : "Access request ID" ,
1116
- generators : teleportRequestGenerator ,
1301
+ generators : teleportGenerators . request ,
1117
1302
} ,
1118
1303
} ,
1119
1304
{
@@ -1122,7 +1307,7 @@ const completionSpec: Fig.Spec = {
1122
1307
args : {
1123
1308
name : "request" ,
1124
1309
description : "Access request ID" ,
1125
- generators : teleportRequestGenerator ,
1310
+ generators : teleportGenerators . request ,
1126
1311
} ,
1127
1312
} ,
1128
1313
{
@@ -1131,21 +1316,11 @@ const completionSpec: Fig.Spec = {
1131
1316
args : {
1132
1317
name : "username" ,
1133
1318
description : "Name of target user" ,
1134
- generators : teleportAccountsGenerator ,
1319
+ generators : teleportGenerators . user ,
1135
1320
} ,
1136
1321
options : [
1137
- {
1138
- name : "--roles" ,
1139
- description : "Roles to be requested" ,
1140
- args : {
1141
- name : "roles" ,
1142
- generators : teleportRolesGenerator ,
1143
- } ,
1144
- } ,
1145
- {
1146
- name : "--reason" ,
1147
- description : "Optional reason message" ,
1148
- } ,
1322
+ teleportOptions . reason ,
1323
+ teleportOptions . roles ,
1149
1324
{
1150
1325
name : "--resource" ,
1151
1326
description : "Resource ID to be requested" ,
@@ -1172,7 +1347,7 @@ const completionSpec: Fig.Spec = {
1172
1347
args : {
1173
1348
name : "request-id" ,
1174
1349
description : "Access request ID" ,
1175
- generators : teleportRequestGenerator ,
1350
+ generators : teleportGenerators . request ,
1176
1351
} ,
1177
1352
} ,
1178
1353
{
@@ -1185,7 +1360,7 @@ const completionSpec: Fig.Spec = {
1185
1360
isRequired : true ,
1186
1361
args : {
1187
1362
name : "author" ,
1188
- generators : teleportAccountsGenerator ,
1363
+ generators : teleportGenerators . user ,
1189
1364
} ,
1190
1365
} ,
1191
1366
{
@@ -1200,7 +1375,7 @@ const completionSpec: Fig.Spec = {
1200
1375
args : {
1201
1376
name : "request-id" ,
1202
1377
description : "Access request ID" ,
1203
- generators : teleportRequestGenerator ,
1378
+ generators : teleportGenerators . request ,
1204
1379
} ,
1205
1380
} ,
1206
1381
] ,
@@ -1209,66 +1384,70 @@ const completionSpec: Fig.Spec = {
1209
1384
{
1210
1385
name : "apps" ,
1211
1386
description : "Operate on applications registered with the cluster" ,
1212
- args : { } ,
1213
1387
requiresSubcommand : true ,
1388
+ priority : 100 ,
1214
1389
subcommands : [
1215
1390
{
1216
1391
name : "ls" ,
1217
1392
description : "List all applications registered with the cluster" ,
1393
+ options : [ teleportOptions . format ] ,
1218
1394
} ,
1219
1395
] ,
1220
1396
} ,
1221
1397
/* tctl db */
1222
1398
{
1223
1399
name : "db" ,
1224
1400
description : "Operate on databases registered with the cluster" ,
1225
- args : { } ,
1226
1401
requiresSubcommand : true ,
1402
+ priority : 100 ,
1227
1403
subcommands : [
1228
1404
{
1229
1405
name : "ls" ,
1230
1406
description : "List all databases registered with the cluster" ,
1407
+ options : [ teleportOptions . format ] ,
1231
1408
} ,
1232
1409
] ,
1233
1410
} ,
1234
1411
/* tctl kube */
1235
1412
{
1236
1413
name : "kube" ,
1237
1414
description : "Operate on registered Kubernetes clusters" ,
1238
- args : { } ,
1239
1415
requiresSubcommand : true ,
1416
+ priority : 100 ,
1240
1417
subcommands : [
1241
1418
{
1242
1419
name : "ls" ,
1243
1420
description :
1244
1421
"List all Kubernetes clusters registered with the cluster" ,
1422
+ options : [ teleportOptions . format ] ,
1245
1423
} ,
1246
1424
] ,
1247
1425
} ,
1248
1426
/* tctl windows_desktops */
1249
1427
{
1250
1428
name : "windows_desktops" ,
1251
1429
description : "Operate on registered Windows desktops" ,
1252
- args : { } ,
1253
1430
requiresSubcommand : true ,
1431
+ priority : 100 ,
1254
1432
subcommands : [
1255
1433
{
1256
1434
name : "ls" ,
1257
1435
description : "List all Windows desktops registered with the cluster" ,
1436
+ options : [ teleportOptions . format ] ,
1258
1437
} ,
1259
1438
] ,
1260
1439
} ,
1261
1440
/* tctl proxy */
1262
1441
{
1263
1442
name : "proxy" ,
1264
1443
description : "Operations with information for cluster proxies" ,
1265
- args : { } ,
1266
1444
requiresSubcommand : true ,
1445
+ priority : 100 ,
1267
1446
subcommands : [
1268
1447
{
1269
1448
name : "ls" ,
1270
1449
description : "Lists proxies connected to the cluster" ,
1271
- options : [ teleportFormatOption ] ,
1450
+ options : [ teleportOptions . format ] ,
1272
1451
} ,
1273
1452
] ,
1274
1453
} ,
@@ -1287,45 +1466,52 @@ const completionSpec: Fig.Spec = {
1287
1466
name : "lock" ,
1288
1467
description : "Create a new lock" ,
1289
1468
args : { } ,
1469
+ priority : 100 ,
1290
1470
options : [
1291
1471
{
1292
1472
name : "--user" ,
1293
1473
description : "Name of a Teleport user to disable" ,
1294
1474
args : {
1295
1475
name : "user" ,
1296
- generators : teleportAccountsGenerator ,
1476
+ generators : teleportGenerators . user ,
1297
1477
} ,
1298
1478
} ,
1299
1479
{
1300
1480
name : "--role" ,
1301
1481
description : "Name of a Teleport role to disable" ,
1302
1482
args : {
1303
1483
name : "role" ,
1304
- generators : teleportRolesGenerator ,
1484
+ generators : teleportGenerators . role ,
1305
1485
} ,
1306
1486
} ,
1307
1487
{
1308
1488
name : "--login" ,
1309
1489
description : "Name of a local UNIX user to disable" ,
1490
+ args : {
1491
+ name : "login" ,
1492
+ } ,
1310
1493
} ,
1311
1494
{
1312
1495
name : "--mfa-device" ,
1313
1496
description : "UUID of a user MFA device to disable" ,
1497
+ args : {
1498
+ name : "device" ,
1499
+ } ,
1314
1500
} ,
1315
1501
{
1316
1502
name : "--windows-desktop" ,
1317
1503
description : "Name of a Windows desktop to disable" ,
1318
1504
args : {
1319
1505
name : "desktop" ,
1320
- generators : teleportWindowsDesktopGenerator ,
1506
+ generators : teleportGenerators . windows_desktop ,
1321
1507
} ,
1322
1508
} ,
1323
1509
{
1324
1510
name : "--access-request" ,
1325
1511
description : "UUID of an access request to disable" ,
1326
1512
args : {
1327
1513
name : "request" ,
1328
- generators : teleportRequestGenerator ,
1514
+ generators : teleportGenerators . request ,
1329
1515
} ,
1330
1516
} ,
1331
1517
{
@@ -1345,16 +1531,16 @@ const completionSpec: Fig.Spec = {
1345
1531
} ,
1346
1532
} ,
1347
1533
{
1348
- name : "-- ttl" ,
1534
+ ... teleportOptions . ttl ,
1349
1535
description : "Time duration after which the lock expires" ,
1350
- args : {
1351
- name : "duration" ,
1352
- description : "Time duration after which the lock expires" ,
1353
- } ,
1354
1536
} ,
1355
1537
{
1356
1538
name : "--server-id" ,
1357
1539
description : "UUID of a Teleport server to disable" ,
1540
+ args : {
1541
+ name : "server-uuid" ,
1542
+ generators : teleportGenerators . node ,
1543
+ } ,
1358
1544
} ,
1359
1545
] ,
1360
1546
} ,
@@ -1364,45 +1550,46 @@ const completionSpec: Fig.Spec = {
1364
1550
description :
1365
1551
"Operate on certificate renewal bots registered with the cluster" ,
1366
1552
requiresSubcommand : true ,
1553
+ args : { } ,
1554
+ priority : 100 ,
1367
1555
subcommands : [
1368
1556
{
1369
1557
name : "ls" ,
1370
1558
description :
1371
1559
"List all certificate renewal bots registered with the cluster" ,
1560
+ options : [ teleportOptions . format ] ,
1372
1561
} ,
1373
1562
{
1374
1563
name : "add" ,
1375
1564
description : "Add a new certificate renewal bot to the cluster" ,
1376
1565
args : {
1377
1566
name : "name" ,
1378
1567
description : "A name to uniquely identify this bot in the cluster" ,
1379
- } ,
1380
- options : [
1381
- {
1382
- name : "--roles" ,
1383
- description : "Roles the bot is able to assume" ,
1384
- isRequired : true ,
1385
- args : {
1386
- name : "roles" ,
1387
- generators : teleportRolesGenerator ,
1568
+ generators : {
1569
+ ...teleportBotsGenerator ,
1570
+ postProcess : function ( out ) {
1571
+ const bots = JSON . parse ( out ) ;
1572
+ return bots . map ( ( bot : Bot ) => {
1573
+ return {
1574
+ name : bot . metadata . name . slice ( 4 ) ,
1575
+ description : "A bot with this name already exists" ,
1576
+ } ;
1577
+ } ) ;
1388
1578
} ,
1389
1579
} ,
1390
- {
1391
- name : "--ttl" ,
1392
- description : "TTL for the bot join token" ,
1393
- } ,
1580
+ } ,
1581
+ options : [
1582
+ teleportOptions . ttl ,
1583
+ teleportOptions . roles ,
1584
+ teleportOptions . logins ,
1394
1585
{
1395
1586
name : "--token" ,
1396
1587
description : "Name of an existing token to use" ,
1397
1588
args : {
1398
1589
name : "token" ,
1399
- generators : teleportTokenGenerator ,
1590
+ generators : teleportGenerators . tokens ,
1400
1591
} ,
1401
1592
} ,
1402
- {
1403
- name : "--logins" ,
1404
- description : "List of allowed SSH logins for the bot user" ,
1405
- } ,
1406
1593
] ,
1407
1594
} ,
1408
1595
{
@@ -1422,6 +1609,7 @@ const completionSpec: Fig.Spec = {
1422
1609
name : "inventory" ,
1423
1610
description : "Manage Teleport instance inventory" ,
1424
1611
requiresSubcommand : true ,
1612
+ priority : 100 ,
1425
1613
subcommands : [
1426
1614
{
1427
1615
name : "status" ,
@@ -1496,6 +1684,7 @@ const completionSpec: Fig.Spec = {
1496
1684
name : "recordings" ,
1497
1685
description : "View and control session recordings" ,
1498
1686
requiresSubcommand : true ,
1687
+ priority : 100 ,
1499
1688
subcommands : [
1500
1689
{
1501
1690
name : "ls" ,
@@ -1508,15 +1697,17 @@ const completionSpec: Fig.Spec = {
1508
1697
name : "alerts" ,
1509
1698
description : "Manage cluster alerts" ,
1510
1699
requiresSubcommand : true ,
1700
+ args : { } ,
1701
+ priority : 100 ,
1511
1702
subcommands : [
1512
1703
{
1513
1704
name : "list" ,
1514
1705
description : "List cluster alerts" ,
1515
1706
options : [
1516
- teleportFormatOption ,
1707
+ teleportOptions . format ,
1517
1708
{
1518
1709
name : "--labels" ,
1519
- description : "List of comma separated labels to filter by labels" ,
1710
+ description : "Filter by labels" ,
1520
1711
args : {
1521
1712
name : "label1=value1,label2=value2" ,
1522
1713
} ,
@@ -1534,7 +1725,7 @@ const completionSpec: Fig.Spec = {
1534
1725
options : [
1535
1726
{
1536
1727
name : "--labels" ,
1537
- description : "List of comma separated labels to filter by labels " ,
1728
+ description : "Which labels should this alert have " ,
1538
1729
args : {
1539
1730
name : "label1=value1,label2=value2" ,
1540
1731
} ,
@@ -1548,7 +1739,7 @@ const completionSpec: Fig.Spec = {
1548
1739
} ,
1549
1740
} ,
1550
1741
{
1551
- name : "-- ttl" ,
1742
+ ... teleportOptions . ttl ,
1552
1743
description :
1553
1744
"Time duration after which the alert expires (default 24h)" ,
1554
1745
} ,
@@ -1573,12 +1764,9 @@ const completionSpec: Fig.Spec = {
1573
1764
generators : teleportAlertGenerator ,
1574
1765
} ,
1575
1766
options : [
1767
+ ...[ teleportOptions . reason ] ,
1576
1768
{
1577
- name : "--reason" ,
1578
- description : "The reason for acknowledging the cluster alert" ,
1579
- } ,
1580
- {
1581
- name : "--ttl" ,
1769
+ ...teleportOptions . ttl ,
1582
1770
description :
1583
1771
"Time duration after which the alert expires (default 24h)" ,
1584
1772
} ,
@@ -1594,9 +1782,10 @@ const completionSpec: Fig.Spec = {
1594
1782
{
1595
1783
name : "create" ,
1596
1784
description : "Create or update a Teleport resource from a YAML file" ,
1785
+ priority : 100 ,
1597
1786
args : {
1598
1787
name : "filename" ,
1599
- template : "filepaths" ,
1788
+ generators : teleportGenerators . yamlFiles ,
1600
1789
} ,
1601
1790
options : [
1602
1791
{
@@ -1609,6 +1798,7 @@ const completionSpec: Fig.Spec = {
1609
1798
{
1610
1799
name : "update" ,
1611
1800
description : "Update resource fields" ,
1801
+ priority : 100 ,
1612
1802
args : {
1613
1803
name : "resource type/resource name" ,
1614
1804
description : "Resource to update" ,
@@ -1617,18 +1807,23 @@ const completionSpec: Fig.Spec = {
1617
1807
options : [
1618
1808
{
1619
1809
name : "--set-labels" ,
1620
- description : "Set labels" ,
1810
+ description : "Replace labels" ,
1811
+ args : {
1812
+ name : "label1=value1,label2=value2" ,
1813
+ } ,
1621
1814
} ,
1622
1815
{
1816
+ ...teleportOptions . ttl ,
1623
1817
name : "--set-ttl" ,
1624
- description : "Set TTL" ,
1818
+ description : "Replace TTL" ,
1625
1819
} ,
1626
1820
] ,
1627
1821
} ,
1628
1822
/* tctl edit */
1629
1823
{
1630
1824
name : "edit" ,
1631
1825
description : "Edit a Teleport resource" ,
1826
+ priority : 100 ,
1632
1827
args : {
1633
1828
name : "resource type/resource name" ,
1634
1829
description : "Resource to edit" ,
@@ -1639,7 +1834,9 @@ const completionSpec: Fig.Spec = {
1639
1834
{
1640
1835
name : "devices" ,
1641
1836
description : "Register and manage trusted devices" ,
1837
+ priority : 100 ,
1642
1838
requiresSubcommand : true ,
1839
+ args : { } ,
1643
1840
subcommands : [
1644
1841
{
1645
1842
name : "add" ,
@@ -1683,7 +1880,7 @@ const completionSpec: Fig.Spec = {
1683
1880
args : {
1684
1881
name : "device" ,
1685
1882
description : "Device ID" ,
1686
- generators : teleportDeviceGenerator ,
1883
+ generators : teleportGenerators . device ,
1687
1884
} ,
1688
1885
} ,
1689
1886
{
@@ -1710,7 +1907,7 @@ const completionSpec: Fig.Spec = {
1710
1907
args : {
1711
1908
name : "device" ,
1712
1909
description : "Device ID" ,
1713
- generators : teleportDeviceGenerator ,
1910
+ generators : teleportGenerators . device ,
1714
1911
} ,
1715
1912
} ,
1716
1913
] ,
@@ -1720,14 +1917,17 @@ const completionSpec: Fig.Spec = {
1720
1917
name : "saml" ,
1721
1918
description : "Operations on SAML auth connectors" ,
1722
1919
requiresSubcommand : true ,
1920
+ priority : 100 ,
1921
+ args : { } ,
1723
1922
subcommands : [
1724
1923
{
1725
1924
name : "export" ,
1726
1925
description : "Export a SAML signing key in .crt format" ,
1727
1926
args : {
1728
1927
name : "connector_name" ,
1928
+ isOptional : true ,
1729
1929
description : "Name of the SAML connector to export the key from" ,
1730
- generators : teleportSAMLConnectorGenerator ,
1930
+ generators : teleportGenerators . connector ,
1731
1931
} ,
1732
1932
} ,
1733
1933
] ,
@@ -1737,6 +1937,8 @@ const completionSpec: Fig.Spec = {
1737
1937
name : [ "acl" , "access-lists" ] ,
1738
1938
description : "Manage access lists" ,
1739
1939
requiresSubcommand : true ,
1940
+ priority : 100 ,
1941
+ args : { } ,
1740
1942
subcommands : [
1741
1943
{
1742
1944
name : "ls" ,
@@ -1768,7 +1970,7 @@ const completionSpec: Fig.Spec = {
1768
1970
{
1769
1971
name : "user" ,
1770
1972
description : "The user name" ,
1771
- generators : teleportAccountsGenerator ,
1973
+ generators : teleportGenerators . user ,
1772
1974
} ,
1773
1975
{
1774
1976
name : "expires" ,
@@ -1796,7 +1998,7 @@ const completionSpec: Fig.Spec = {
1796
1998
{
1797
1999
name : "user" ,
1798
2000
description : "The user name" ,
1799
- generators : teleportAccountsGenerator ,
2001
+ generators : teleportGenerators . user ,
1800
2002
} ,
1801
2003
] ,
1802
2004
} ,
@@ -1818,6 +2020,7 @@ const completionSpec: Fig.Spec = {
1818
2020
name : "login_rule" ,
1819
2021
description : "Test login rules" ,
1820
2022
requiresSubcommand : true ,
2023
+ priority : 100 ,
1821
2024
subcommands : [
1822
2025
{
1823
2026
name : "test" ,
@@ -1831,6 +2034,8 @@ const completionSpec: Fig.Spec = {
1831
2034
description :
1832
2035
"A family of commands for configuring and testing auth connectors (SSO)" ,
1833
2036
requiresSubcommand : true ,
2037
+ priority : 100 ,
2038
+ args : { } ,
1834
2039
subcommands : [
1835
2040
{
1836
2041
name : "configure" ,
@@ -1844,6 +2049,9 @@ const completionSpec: Fig.Spec = {
1844
2049
{
1845
2050
name : "--name" ,
1846
2051
description : "Connector name" ,
2052
+ args : {
2053
+ name : "name" ,
2054
+ } ,
1847
2055
} ,
1848
2056
{
1849
2057
name : "--teams-to-roles" ,
@@ -1856,26 +2064,44 @@ const completionSpec: Fig.Spec = {
1856
2064
{
1857
2065
name : "--display" ,
1858
2066
description : "Sets the connector display name" ,
2067
+ args : {
2068
+ name : "display-name" ,
2069
+ } ,
1859
2070
} ,
1860
2071
{
1861
2072
name : "--id" ,
1862
2073
description : "GitHub app client ID" ,
2074
+ args : {
2075
+ name : "id" ,
2076
+ } ,
1863
2077
} ,
1864
2078
{
1865
2079
name : "--secret" ,
1866
2080
description : "GitHub app client secret" ,
2081
+ args : {
2082
+ name : "secret" ,
2083
+ } ,
1867
2084
} ,
1868
2085
{
1869
2086
name : "--endpoint-url" ,
1870
2087
description : "Endpoint URL for GitHub instance" ,
2088
+ args : {
2089
+ name : "endpoint-url" ,
2090
+ } ,
1871
2091
} ,
1872
2092
{
1873
2093
name : "--api-endpoint-url" ,
1874
2094
description : "API endpoint URL for GitHub instance" ,
2095
+ args : {
2096
+ name : "api-endpoint-url" ,
2097
+ } ,
1875
2098
} ,
1876
2099
{
1877
2100
name : "--redirect-url" ,
1878
2101
description : "Authorization callback URL" ,
2102
+ args : {
2103
+ name : "redirect-url" ,
2104
+ } ,
1879
2105
} ,
1880
2106
{
1881
2107
name : "--ignore-missing-roles" ,
@@ -1895,15 +2121,15 @@ const completionSpec: Fig.Spec = {
1895
2121
name : "filename" ,
1896
2122
description :
1897
2123
"Connector resource definition filename. Empty for stdin" ,
1898
- isOptional : true ,
1899
- template : "filepaths" ,
2124
+ generators : teleportGenerators . yamlFiles ,
1900
2125
} ,
1901
2126
} ,
1902
2127
] ,
1903
2128
} ,
1904
2129
/* tctl version */
1905
2130
{
1906
2131
name : "version" ,
2132
+ priority : 100 ,
1907
2133
description : "Print the version of your tctl binary" ,
1908
2134
} ,
1909
2135
] ,
@@ -1924,7 +2150,7 @@ const completionSpec: Fig.Spec = {
1924
2150
isPersistent : true ,
1925
2151
args : {
1926
2152
name : "config" ,
1927
- template : "filepaths" ,
2153
+ generators : teleportGenerators . yamlFiles ,
1928
2154
} ,
1929
2155
} ,
1930
2156
{
0 commit comments