@@ -2,18 +2,21 @@ package cmd
2
2
3
3
import (
4
4
"fmt"
5
+ "io"
5
6
"os"
6
7
"sort"
7
8
"text/tabwriter"
8
9
9
10
"cdr.dev/coder-cli/coder-sdk"
10
11
"github.com/spf13/cobra"
12
+ "golang.org/x/xerrors"
11
13
)
12
14
13
15
func makeResourceCmd () * cobra.Command {
14
16
cmd := & cobra.Command {
15
- Use : "resources" ,
16
- Short : "manager Coder resources with platform-level context (users, organizations, environments)" ,
17
+ Use : "resources" ,
18
+ Short : "manager Coder resources with platform-level context (users, organizations, environments)" ,
19
+ Hidden : true ,
17
20
}
18
21
cmd .AddCommand (resourceTop ())
19
22
return cmd
@@ -24,15 +27,16 @@ func resourceTop() *cobra.Command {
24
27
Use : "top" ,
25
28
RunE : func (cmd * cobra.Command , args []string ) error {
26
29
ctx := cmd .Context ()
27
-
28
30
client , err := newClient ()
29
31
if err != nil {
30
32
return err
31
33
}
32
34
33
- envs , err := client .ListEnvironments (ctx )
35
+ // NOTE: it's not worth parrallelizing these calls yet given that this specific endpoint
36
+ // takes about 20x times longer than the other two
37
+ envs , err := client .Environments (ctx )
34
38
if err != nil {
35
- return err
39
+ return xerrors . Errorf ( "get environments %w" , err )
36
40
}
37
41
38
42
userEnvs := make (map [string ][]coder.Environment )
@@ -42,51 +46,55 @@ func resourceTop() *cobra.Command {
42
46
43
47
users , err := client .Users (ctx )
44
48
if err != nil {
45
- return err
49
+ return xerrors . Errorf ( "get users: %w" , err )
46
50
}
47
51
48
- orgs := make (map [string ]coder.Organization )
52
+ orgIDMap := make (map [string ]coder.Organization )
49
53
orglist , err := client .Organizations (ctx )
50
54
if err != nil {
51
- return err
55
+ return xerrors . Errorf ( "get organizations: %w" , err )
52
56
}
53
57
for _ , o := range orglist {
54
- orgs [o .ID ] = o
55
- }
56
-
57
- tabwriter := tabwriter .NewWriter (os .Stdout , 0 , 0 , 4 , ' ' , 0 )
58
- var userResources []aggregatedUser
59
- for _ , u := range users {
60
- // truncate user names to ensure tabwriter doesn't push our entire table too far
61
- u .Name = truncate (u .Name , 20 , "..." )
62
- userResources = append (userResources , aggregatedUser {User : u , resources : aggregateEnvResources (userEnvs [u .ID ])})
63
- }
64
- sort .Slice (userResources , func (i , j int ) bool {
65
- return userResources [i ].cpuAllocation > userResources [j ].cpuAllocation
66
- })
67
-
68
- for _ , u := range userResources {
69
- _ , _ = fmt .Fprintf (tabwriter , "%s\t (%s)\t %s" , u .Name , u .Email , u .resources )
70
- if verbose {
71
- if len (userEnvs [u .ID ]) > 0 {
72
- _ , _ = fmt .Fprintf (tabwriter , "\f " )
73
- }
74
- for _ , env := range userEnvs [u .ID ] {
75
- _ , _ = fmt .Fprintf (tabwriter , "\t " )
76
- _ , _ = fmt .Fprintln (tabwriter , fmtEnvResources (env , orgs ))
77
- }
78
- }
79
- fmt .Fprint (tabwriter , "\n " )
58
+ orgIDMap [o .ID ] = o
80
59
}
81
- _ = tabwriter .Flush ()
82
60
61
+ printResourceTop (os .Stdout , users , orgIDMap , userEnvs )
83
62
return nil
84
63
},
85
64
}
86
65
87
66
return cmd
88
67
}
89
68
69
+ func printResourceTop (writer io.Writer , users []coder.User , orgIDMap map [string ]coder.Organization , userEnvs map [string ][]coder.Environment ) {
70
+ tabwriter := tabwriter .NewWriter (writer , 0 , 0 , 4 , ' ' , 0 )
71
+ defer func () { _ = tabwriter .Flush () }()
72
+
73
+ var userResources []aggregatedUser
74
+ for _ , u := range users {
75
+ // truncate user names to ensure tabwriter doesn't push our entire table too far
76
+ u .Name = truncate (u .Name , 20 , "..." )
77
+ userResources = append (userResources , aggregatedUser {User : u , resources : aggregateEnvResources (userEnvs [u .ID ])})
78
+ }
79
+ sort .Slice (userResources , func (i , j int ) bool {
80
+ return userResources [i ].cpuAllocation > userResources [j ].cpuAllocation
81
+ })
82
+
83
+ for _ , u := range userResources {
84
+ _ , _ = fmt .Fprintf (tabwriter , "%s\t (%s)\t %s" , u .Name , u .Email , u .resources )
85
+ if verbose {
86
+ if len (userEnvs [u .ID ]) > 0 {
87
+ _ , _ = fmt .Fprintf (tabwriter , "\f " )
88
+ }
89
+ for _ , env := range userEnvs [u .ID ] {
90
+ _ , _ = fmt .Fprintf (tabwriter , "\t " )
91
+ _ , _ = fmt .Fprintln (tabwriter , fmtEnvResources (env , orgIDMap ))
92
+ }
93
+ }
94
+ _ , _ = fmt .Fprint (tabwriter , "\n " )
95
+ }
96
+ }
97
+
90
98
type aggregatedUser struct {
91
99
coder.User
92
100
resources
0 commit comments