@@ -28,6 +28,7 @@ type resourceTopOptions struct {
28
28
user string
29
29
org string
30
30
sortBy string
31
+ provider string
31
32
showEmptyGroups bool
32
33
}
33
34
@@ -41,11 +42,13 @@ func resourceTop() *cobra.Command {
41
42
Example : `coder resources top --group org
42
43
coder resources top --group org --verbose --org DevOps
43
44
coder resources top --group user --verbose --user name@example.com
45
+ coder resources top --group provider --verbose --provider myprovider
44
46
coder resources top --sort-by memory --show-empty` ,
45
47
}
46
- cmd .Flags ().StringVar (& options .group , "group" , "user" , "the grouping parameter (user|org)" )
48
+ cmd .Flags ().StringVar (& options .group , "group" , "user" , "the grouping parameter (user|org|provider )" )
47
49
cmd .Flags ().StringVar (& options .user , "user" , "" , "filter by a user email" )
48
50
cmd .Flags ().StringVar (& options .org , "org" , "" , "filter by the name of an organization" )
51
+ cmd .Flags ().StringVar (& options .provider , "provider" , "" , "filter by the name of a workspace provider" )
49
52
cmd .Flags ().StringVar (& options .sortBy , "sort-by" , "cpu" , "field to sort aggregate groups and environments by (cpu|memory)" )
50
53
cmd .Flags ().BoolVar (& options .showEmptyGroups , "show-empty" , false , "show groups with zero active environments" )
51
54
@@ -84,13 +87,20 @@ func runResourceTop(options *resourceTopOptions) func(cmd *cobra.Command, args [
84
87
return xerrors .Errorf ("get organizations: %w" , err )
85
88
}
86
89
90
+ providers , err := client .WorkspaceProviders (ctx )
91
+ if err != nil {
92
+ return xerrors .Errorf ("get workspace providers: %w" , err )
93
+ }
94
+
87
95
var groups []groupable
88
96
var labeler envLabeler
89
97
switch options .group {
90
98
case "user" :
91
99
groups , labeler = aggregateByUser (users , orgs , envs , * options )
92
100
case "org" :
93
101
groups , labeler = aggregateByOrg (users , orgs , envs , * options )
102
+ case "provider" :
103
+ groups , labeler = aggregateByProvider (providers .Kubernetes , orgs , envs , * options )
94
104
default :
95
105
return xerrors .Errorf ("unknown --group %q" , options .group )
96
106
}
@@ -143,6 +153,28 @@ func aggregateByOrg(users []coder.User, orgs []coder.Organization, envs []coder.
143
153
return groups , userLabeler {userIDMap }
144
154
}
145
155
156
+ func aggregateByProvider (providers []coder.KubernetesProvider , orgs []coder.Organization , envs []coder.Environment , options resourceTopOptions ) ([]groupable , envLabeler ) {
157
+ var groups []groupable
158
+ providerIDMap := make (map [string ]coder.KubernetesProvider )
159
+ for _ , p := range providers {
160
+ providerIDMap [p .ID ] = p
161
+ }
162
+ providerEnvs := make (map [string ][]coder.Environment , len (orgs ))
163
+ for _ , e := range envs {
164
+ if options .provider != "" && providerIDMap [e .ResourcePoolID ].Name != options .provider {
165
+ continue
166
+ }
167
+ providerEnvs [e .ResourcePoolID ] = append (providerEnvs [e .ResourcePoolID ], e )
168
+ }
169
+ for _ , p := range providers {
170
+ if options .provider != "" && p .Name != options .provider {
171
+ continue
172
+ }
173
+ groups = append (groups , providerGrouping {provider : p , envs : providerEnvs [p .ID ]})
174
+ }
175
+ return groups , providerLabeler {providerIDMap }
176
+ }
177
+
146
178
// groupable specifies a structure capable of being an aggregation group of environments (user, org, all).
147
179
type groupable interface {
148
180
header () string
@@ -179,6 +211,19 @@ func (o orgGrouping) header() string {
179
211
return fmt .Sprintf ("%s\t (%v member%s)" , truncate (o .org .Name , 20 , "..." ), len (o .org .Members ), plural )
180
212
}
181
213
214
+ type providerGrouping struct {
215
+ provider coder.KubernetesProvider
216
+ envs []coder.Environment
217
+ }
218
+
219
+ func (p providerGrouping ) environments () []coder.Environment {
220
+ return p .envs
221
+ }
222
+
223
+ func (p providerGrouping ) header () string {
224
+ return fmt .Sprintf ("%s\t " , truncate (p .provider .Name , 20 , "..." ))
225
+ }
226
+
182
227
func printResourceTop (writer io.Writer , groups []groupable , labeler envLabeler , showEmptyGroups bool , sortBy string ) error {
183
228
tabwriter := tabwriter .NewWriter (writer , 0 , 0 , 4 , ' ' , 0 )
184
229
defer func () { _ = tabwriter .Flush () }()
@@ -287,6 +332,14 @@ func (u userLabeler) label(e coder.Environment) string {
287
332
return fmt .Sprintf ("[user: %s]" , u .userMap [e .UserID ].Email )
288
333
}
289
334
335
+ type providerLabeler struct {
336
+ providerMap map [string ]coder.KubernetesProvider
337
+ }
338
+
339
+ func (p providerLabeler ) label (e coder.Environment ) string {
340
+ return fmt .Sprintf ("[provider: %s]" , p .providerMap [e .ResourcePoolID ].Name )
341
+ }
342
+
290
343
func aggregateEnvResources (envs []coder.Environment ) resources {
291
344
var aggregate resources
292
345
for _ , e := range envs {
0 commit comments