• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

astronomer / astro-cli / 357629b1-60cb-43d6-9ac2-8b5249dd574b

26 Mar 2026 02:28PM UTC coverage: 36.086% (-0.3%) from 36.378%
357629b1-60cb-43d6-9ac2-8b5249dd574b

Pull #2060

circleci

jlaneve
fix: add include/ to PYTHONPATH in standalone mode

Standalone mode's buildEnv() did not set PYTHONPATH to include the
project's include/ directory. In Docker mode the Astronomer runtime
image bakes /usr/local/airflow/include into PYTHONPATH, but standalone
had no equivalent — causing import failures for any user modules in
include/ during pytest, parse, and start.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pull Request #2060: fix: add include/ to PYTHONPATH in standalone mode

7 of 8 new or added lines in 1 file covered. (87.5%)

403 existing lines in 8 files now uncovered.

24494 of 67876 relevant lines covered (36.09%)

8.63 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.24
/cmd/cloud/workspace.go
1
package cloud
2

3
import (
4
        "fmt"
5
        "io"
6
        "os"
7
        "strconv"
8
        "strings"
9

10
        astrocore "github.com/astronomer/astro-cli/astro-client-core"
11
        "github.com/astronomer/astro-cli/cloud/organization"
12
        "github.com/astronomer/astro-cli/cloud/team"
13
        "github.com/astronomer/astro-cli/cloud/user"
14
        "github.com/astronomer/astro-cli/cloud/workspace"
15
        workspacetoken "github.com/astronomer/astro-cli/cloud/workspace-token"
16
        "github.com/astronomer/astro-cli/pkg/input"
17
        "github.com/astronomer/astro-cli/pkg/printutil"
18

19
        "github.com/pkg/errors"
20
        "github.com/spf13/cobra"
21
)
22

23
var (
24
        errInvalidWorkspaceRoleKey = errors.New("invalid workspace role selection")
25
        workspaceID                string
26
        addWorkspaceRole           string
27
        updateWorkspaceRole        string
28
        workspaceName              string
29
        workspaceDescription       string
30
        enforceCD                  string
31
        tokenName                  string
32
        tokenDescription           string
33
        tokenRole                  string
34
        orgTokenName               string
35
        tokenID                    string
36
        orgTokenID                 string
37
        workspaceTokenID           string
38
        cleanTokenOutput           bool
39
        forceRotate                bool
40
        tokenExpiration            int
41
        validWorkspaceRoles        []string
42
)
43

44
const (
45
        allowedWorkspaceRoleNames      = "WORKSPACE_MEMBER, WORKSPACE_AUTHOR, WORKSPACE_OPERATOR, WORKSPACE_OWNER"
46
        allowedWorkspaceRoleNamesProse = "WORKSPACE_MEMBER, WORKSPACE_AUTHOR, WORKSPACE_OPERATOR, and WORKSPACE_OWNER"
47
)
48

49
func init() {
1✔
50
        validWorkspaceRoles = []string{"WORKSPACE_MEMBER", "WORKSPACE_AUTHOR", "WORKSPACE_OPERATOR", "WORKSPACE_OWNER"}
1✔
51
}
1✔
52

53
func newWorkspaceCmd(out io.Writer) *cobra.Command {
106✔
54
        cmd := &cobra.Command{
106✔
55
                Use:     "workspace",
106✔
56
                Aliases: []string{"wo"},
106✔
57
                Short:   "Manage Astro Workspaces",
106✔
58
                Long:    "Create and manage Workspaces on Astro. Workspaces can contain multiple Deployments and can be shared across users.",
106✔
59
        }
106✔
60
        cmd.AddCommand(
106✔
61
                newWorkspaceListCmd(out),
106✔
62
                newWorkspaceSwitchCmd(out),
106✔
63
                newWorkspaceCreateCmd(out),
106✔
64
                newWorkspaceUpdateCmd(out),
106✔
65
                newWorkspaceDeleteCmd(out),
106✔
66
                newWorkspaceUserRootCmd(out),
106✔
67
                newWorkspaceTokenRootCmd(out),
106✔
68
                newWorkspaceTeamRootCmd(out),
106✔
69
        )
106✔
70
        return cmd
106✔
71
}
106✔
72

73
func newWorkspaceListCmd(out io.Writer) *cobra.Command {
106✔
74
        cmd := &cobra.Command{
106✔
75
                Use:     "list",
106✔
76
                Aliases: []string{"ls"},
106✔
77
                Short:   "List all Astro Workspaces in your organization",
106✔
78
                Long:    "List all Astro Workspaces in your organization.",
106✔
79
                RunE: func(cmd *cobra.Command, args []string) error {
107✔
80
                        return workspaceList(cmd, out)
1✔
81
                },
1✔
82
        }
83
        return cmd
106✔
84
}
85

86
func newWorkspaceSwitchCmd(out io.Writer) *cobra.Command {
106✔
87
        cmd := &cobra.Command{
106✔
88
                Use:     "switch [workspace name/id]",
106✔
89
                Aliases: []string{"sw"},
106✔
90
                Short:   "Switch to a different Astro Workspace",
106✔
91
                Long:    "Switch to a different Astro Workspace",
106✔
92
                Args:    cobra.MaximumNArgs(1),
106✔
93
                RunE: func(cmd *cobra.Command, args []string) error {
107✔
94
                        return workspaceSwitch(cmd, out, args)
1✔
95
                },
1✔
96
        }
97
        return cmd
106✔
98
}
99

100
func newWorkspaceCreateCmd(out io.Writer) *cobra.Command {
106✔
101
        cmd := &cobra.Command{
106✔
102
                Use:     "create",
106✔
103
                Aliases: []string{"cr"},
106✔
104
                Short:   "Create an Astro Workspace",
106✔
105
                Long:    "Create an Astro Workspace",
106✔
106
                RunE: func(cmd *cobra.Command, args []string) error {
110✔
107
                        return workspaceCreate(cmd, out)
4✔
108
                },
4✔
109
        }
110
        cmd.Flags().StringVarP(&workspaceName, "name", "n", "", "The Workspace's name. If the name contains a space, specify the entire name within quotes \"\" ")
106✔
111
        cmd.Flags().StringVarP(&workspaceDescription, "description", "d", "", "Description of the Workspace. If the description contains a space, specify the entire description in quotes \"\"")
106✔
112
        cmd.Flags().StringVarP(&enforceCD, "enforce-cicd", "e", "OFF", "Provide this flag either ON/OFF. ON means deploys to deployments must use an API Key or Token. This essentially forces Deploys to happen through CI/CD")
106✔
113
        return cmd
106✔
114
}
115

116
func newWorkspaceUpdateCmd(out io.Writer) *cobra.Command {
106✔
117
        cmd := &cobra.Command{
106✔
118
                Use:     "update [workspace_id]",
106✔
119
                Aliases: []string{"up"},
106✔
120
                Short:   "Update an Astro Workspace",
106✔
121
                Long:    "Update an Astro Workspace",
106✔
122
                Args:    cobra.MaximumNArgs(1),
106✔
123
                RunE: func(cmd *cobra.Command, args []string) error {
111✔
124
                        return workspaceUpdate(cmd, out, args)
5✔
125
                },
5✔
126
        }
127
        cmd.Flags().StringVarP(&workspaceName, "name", "n", "", "The Workspace's name. If the name contains a space, specify the entire name within quotes \"\" ")
106✔
128
        cmd.Flags().StringVarP(&workspaceDescription, "description", "d", "", "Description of the Workspace. If the description contains a space, specify the entire description in quotes \"\"")
106✔
129
        cmd.Flags().StringVarP(&enforceCD, "enforce-cicd", "e", "OFF", "Provide this flag either ON/OFF. ON means deploys to deployments must use an API Key or Token. This essentially forces Deploys to happen through CI/CD")
106✔
130
        return cmd
106✔
131
}
132

133
func newWorkspaceDeleteCmd(out io.Writer) *cobra.Command {
106✔
134
        cmd := &cobra.Command{
106✔
135
                Use:     "delete [workspace_id]",
106✔
136
                Aliases: []string{"de"},
106✔
137
                Short:   "Delete an Astro Workspace",
106✔
138
                Long:    "Delete an Astro Workspace",
106✔
139
                Args:    cobra.MaximumNArgs(1),
106✔
140
                RunE: func(cmd *cobra.Command, args []string) error {
111✔
141
                        return workspaceDelete(cmd, out, args)
5✔
142
                },
5✔
143
        }
144
        return cmd
106✔
145
}
146

147
func newWorkspaceUserRootCmd(out io.Writer) *cobra.Command {
106✔
148
        cmd := &cobra.Command{
106✔
149
                Use:     "user",
106✔
150
                Aliases: []string{"us", "users"},
106✔
151
                Short:   "Manage users in your Astro Workspace",
106✔
152
                Long:    "Manage users in your Astro Workspace.",
106✔
153
        }
106✔
154
        cmd.SetOut(out)
106✔
155
        cmd.AddCommand(
106✔
156
                newWorkspaceUserListCmd(out),
106✔
157
                newWorkspaceUserUpdateCmd(out),
106✔
158
                newWorkspaceUserRemoveCmd(out),
106✔
159
                newWorkspaceUserAddCmd(out),
106✔
160
        )
106✔
161
        cmd.PersistentFlags().StringVar(&workspaceID, "workspace-id", "", "workspace where you'd like to manage users")
106✔
162

106✔
163
        return cmd
106✔
164
}
106✔
165

166
func newWorkspaceUserAddCmd(out io.Writer) *cobra.Command {
106✔
167
        cmd := &cobra.Command{
106✔
168
                Use:   "add [email]",
106✔
169
                Short: "Add a user to an Astro Workspace with a specific role",
106✔
170
                Long:  "Add a user to an Astro Workspace with a specific role\n$astro workspace user add [email] --role [" + allowedWorkspaceRoleNames + "].",
106✔
171
                RunE: func(cmd *cobra.Command, args []string) error {
111✔
172
                        return addWorkspaceUser(cmd, args, out)
5✔
173
                },
5✔
174
        }
175
        cmd.Flags().StringVarP(&addWorkspaceRole, "role", "r", "WORKSPACE_MEMBER", "The role for the "+
106✔
176
                "new user. Possible values are "+allowedWorkspaceRoleNamesProse)
106✔
177
        return cmd
106✔
178
}
179

180
func newWorkspaceUserListCmd(out io.Writer) *cobra.Command {
106✔
181
        cmd := &cobra.Command{
106✔
182
                Use:     "list",
106✔
183
                Aliases: []string{"ls"},
106✔
184
                Short:   "List all the users in an Astro Workspace",
106✔
185
                Long:    "List all the users in an Astro Workspace",
106✔
186
                RunE: func(cmd *cobra.Command, args []string) error {
108✔
187
                        return listWorkspaceUser(cmd, out)
2✔
188
                },
2✔
189
        }
190
        return cmd
106✔
191
}
192

193
func newWorkspaceUserUpdateCmd(out io.Writer) *cobra.Command {
106✔
194
        cmd := &cobra.Command{
106✔
195
                Use:     "update [email]",
106✔
196
                Aliases: []string{"up"},
106✔
197
                Short:   "Update a the role of a user in an Astro Workspace",
106✔
198
                Long:    "Update the role of a user in an Astro Workspace\n$astro workspace user update [email] --role [" + allowedWorkspaceRoleNames + "].",
106✔
199
                RunE: func(cmd *cobra.Command, args []string) error {
111✔
200
                        return updateWorkspaceUser(cmd, args, out)
5✔
201
                },
5✔
202
        }
203
        cmd.Flags().StringVarP(&updateWorkspaceRole, "role", "r", "", "The new role for the "+
106✔
204
                "user. Possible values are "+allowedWorkspaceRoleNamesProse)
106✔
205
        return cmd
106✔
206
}
207

208
func newWorkspaceUserRemoveCmd(out io.Writer) *cobra.Command {
106✔
209
        cmd := &cobra.Command{
106✔
210
                Use:     "remove",
106✔
211
                Aliases: []string{"rm"},
106✔
212
                Short:   "Remove a user from an Astro Workspace",
106✔
213
                Long:    "Remove a user from an Astro Workspace",
106✔
214
                RunE: func(cmd *cobra.Command, args []string) error {
110✔
215
                        return removeWorkspaceUser(cmd, args, out)
4✔
216
                },
4✔
217
        }
218
        return cmd
106✔
219
}
220

221
//nolint:dupl
222
func newWorkspaceTokenRootCmd(out io.Writer) *cobra.Command {
106✔
223
        cmd := &cobra.Command{
106✔
224
                Use:     "token",
106✔
225
                Aliases: []string{"to"},
106✔
226
                Short:   "Manage tokens in your Astro Workspace",
106✔
227
                Long:    "Manage tokens in your Astro Workspace.",
106✔
228
        }
106✔
229
        cmd.SetOut(out)
106✔
230
        cmd.AddCommand(
106✔
231
                newWorkspaceTokenListCmd(out),
106✔
232
                newWorkspaceTokenCreateCmd(out),
106✔
233
                newWorkspaceTokenUpdateCmd(out),
106✔
234
                newWorkspaceTokenRotateCmd(out),
106✔
235
                newWorkspaceTokenDeleteCmd(out),
106✔
236
                newWorkspaceTokenAddOrgTokenCmd(out),
106✔
237
                newWorkspaceOrgTokenManageCmd(out),
106✔
238
        )
106✔
239
        cmd.PersistentFlags().StringVar(&workspaceID, "workspace-id", "", "workspace where you would like to manage tokens")
106✔
240
        return cmd
106✔
241
}
106✔
242

243
//nolint:dupl
244
func newWorkspaceTokenListCmd(out io.Writer) *cobra.Command {
106✔
245
        cmd := &cobra.Command{
106✔
246
                Use:     "list",
106✔
247
                Aliases: []string{"ls"},
106✔
248
                Short:   "List all the API tokens in an Astro Workspace",
106✔
249
                Long:    "List all the API tokens in an Astro Workspace",
106✔
250
                RunE: func(cmd *cobra.Command, args []string) error {
110✔
251
                        return listWorkspaceToken(cmd, out)
4✔
252
                },
4✔
253
        }
254
        return cmd
106✔
255
}
256

257
//nolint:dupl
258
func newWorkspaceTeamRootCmd(out io.Writer) *cobra.Command {
106✔
259
        cmd := &cobra.Command{
106✔
260
                Use:     "team",
106✔
261
                Aliases: []string{"te", "teams"},
106✔
262
                Short:   "Manage teams in your Astro Workspace",
106✔
263
                Long:    "Manage teams in your Astro Workspace.",
106✔
264
        }
106✔
265
        cmd.SetOut(out)
106✔
266
        cmd.AddCommand(
106✔
267
                newWorkspaceTeamListCmd(out),
106✔
268
                newWorkspaceTeamUpdateCmd(out),
106✔
269
                newWorkspaceTeamRemoveCmd(out),
106✔
270
                newWorkspaceTeamAddCmd(out),
106✔
271
        )
106✔
272
        return cmd
106✔
273
}
106✔
274

275
//nolint:dupl
276
func newWorkspaceTeamListCmd(out io.Writer) *cobra.Command {
106✔
277
        cmd := &cobra.Command{
106✔
278
                Use:     "list",
106✔
279
                Aliases: []string{"ls"},
106✔
280
                Short:   "List all the teams in an Astro Workspace",
106✔
281
                Long:    "List all the teams in an Astro Workspace",
106✔
282
                RunE: func(cmd *cobra.Command, args []string) error {
108✔
283
                        return listWorkspaceTeam(cmd, out)
2✔
284
                },
2✔
285
        }
286
        return cmd
106✔
287
}
288

289
//nolint:dupl
290
func newWorkspaceTokenCreateCmd(out io.Writer) *cobra.Command {
106✔
291
        cmd := &cobra.Command{
106✔
292
                Use:     "create",
106✔
293
                Aliases: []string{"cr"},
106✔
294
                Short:   "Create an API token in an Astro Workspace",
106✔
295
                Long:    "Create an API token in an Astro Workspace\n$astro workspace token create --name [token name] --role [" + allowedWorkspaceRoleNames + "].",
106✔
296
                RunE: func(cmd *cobra.Command, args []string) error {
110✔
297
                        return createWorkspaceToken(cmd, out)
4✔
298
                },
4✔
299
        }
300
        cmd.Flags().StringVarP(&tokenName, "name", "n", "", "The token's name. If the name contains a space, specify the entire name within quotes \"\" ")
106✔
301
        cmd.Flags().BoolVarP(&cleanTokenOutput, "clean-output", "c", false, "Print only the token as output. For use of the command in scripts")
106✔
302
        cmd.Flags().StringVarP(&tokenDescription, "description", "d", "", "Description of the token. If the description contains a space, specify the entire description within quotes \"\"")
106✔
303
        cmd.Flags().StringVarP(&tokenRole, "role", "r", "", "The role for the "+
106✔
304
                "token. Possible values are "+allowedWorkspaceRoleNamesProse)
106✔
305
        cmd.Flags().IntVarP(&tokenExpiration, "expiration", "e", 0, "Expiration of the token in days. If the flag isn't used the token won't have an expiration. Must be between 1 and 3650 days. ")
106✔
306
        return cmd
106✔
307
}
308

309
//nolint:dupl
310
func newWorkspaceTokenUpdateCmd(out io.Writer) *cobra.Command {
106✔
311
        cmd := &cobra.Command{
106✔
312
                Use:     "update [TOKEN_ID]",
106✔
313
                Aliases: []string{"up"},
106✔
314
                Short:   "Update a Workspace or Organaization API token",
106✔
315
                Long:    "Update a Workspace or Organaization API token that has a role in an Astro Workspace\n$astro workspace token update [TOKEN_ID] --name [new token name] --role [" + allowedWorkspaceRoleNames + "].",
106✔
316
                RunE: func(cmd *cobra.Command, args []string) error {
110✔
317
                        return updateWorkspaceToken(cmd, args, out)
4✔
318
                },
4✔
319
        }
320
        cmd.Flags().StringVarP(&name, "name", "t", "", "The current name of the token. If the name contains a space, specify the entire name within quotes \"\" ")
106✔
321
        cmd.Flags().StringVarP(&tokenName, "new-name", "n", "", "The token's new name. If the name contains a space, specify the entire name within quotes \"\" ")
106✔
322
        cmd.Flags().StringVarP(&tokenDescription, "description", "d", "", "updated description of the token. If the description contains a space, specify the entire description in quotes \"\"")
106✔
323
        cmd.Flags().StringVarP(&tokenRole, "role", "r", "", "The new role for the "+
106✔
324
                "token. Possible values are "+allowedWorkspaceRoleNamesProse)
106✔
325
        return cmd
106✔
326
}
327

328
//nolint:dupl
329
func newWorkspaceTokenRotateCmd(out io.Writer) *cobra.Command {
106✔
330
        cmd := &cobra.Command{
106✔
331
                Use:     "rotate [TOKEN_ID]",
106✔
332
                Aliases: []string{"ro"},
106✔
333
                Short:   "Rotate a Workspace API token",
106✔
334
                Long:    "Rotate a Workspace API token. You can only rotate Workspace API tokens. You cannot rotate Organization API tokens with this command",
106✔
335
                RunE: func(cmd *cobra.Command, args []string) error {
111✔
336
                        return rotateWorkspaceToken(cmd, args, out)
5✔
337
                },
5✔
338
        }
339
        cmd.Flags().BoolVarP(&cleanTokenOutput, "clean-output", "c", false, "Print only the token as output. For use of the command in scripts")
106✔
340
        cmd.Flags().StringVarP(&name, "name", "t", "", "The name of the token to be rotated. If the name contains a space, specify the entire name within quotes \"\" ")
106✔
341
        cmd.Flags().BoolVarP(&forceRotate, "force", "f", false, "Rotate the Workspace API token without showing a warning")
106✔
342

106✔
343
        return cmd
106✔
344
}
345

346
//nolint:dupl
347
func newWorkspaceTokenDeleteCmd(out io.Writer) *cobra.Command {
106✔
348
        cmd := &cobra.Command{
106✔
349
                Use:     "delete [TOKEN_ID]",
106✔
350
                Aliases: []string{"de"},
106✔
351
                Short:   "Delete a Workspace API token or remove an Organization API token from a Workspace",
106✔
352
                Long:    "Delete a Workspace API token or remove an Organization API token from a Workspace",
106✔
353
                RunE: func(cmd *cobra.Command, args []string) error {
111✔
354
                        return deleteWorkspaceToken(cmd, args, out)
5✔
355
                },
5✔
356
        }
357
        cmd.Flags().StringVarP(&name, "name", "t", "", "The name of the token to be deleted. If the name contains a space, specify the entire name within quotes \"\" ")
106✔
358
        cmd.Flags().BoolVarP(&forceDelete, "force", "f", false, "Delete or remove the API token without showing a warning")
106✔
359

106✔
360
        return cmd
106✔
361
}
362

363
//nolint:dupl
364
func newWorkspaceTokenAddOrgTokenCmd(out io.Writer) *cobra.Command {
106✔
365
        cmd := &cobra.Command{
106✔
366
                Use:   "add [ORG_TOKEN_ID]",
106✔
367
                Short: "Add an Organization API token to an Astro Workspace",
106✔
368
                Long:  "Add an Organization API token to an Astro Workspace\n$astro workspace token add [ORG_TOKEN_ID] --org-token-name [token name] --role [" + allowedWorkspaceRoleNames + "].",
106✔
369
                RunE: func(cmd *cobra.Command, args []string) error {
111✔
370
                        return addOrgTokenToWorkspace(cmd, args, out)
5✔
371
                },
5✔
372
        }
373
        cmd.Flags().StringVarP(&orgTokenName, "org-token-name", "n", "", "The name of the Organization API token you want to add to a Workspace. If the name contains a space, specify the entire name within quotes \"\" ")
106✔
374
        cmd.Flags().StringVarP(&tokenRole, "role", "r", "", "The Workspace role to grant to the "+
106✔
375
                "Organization API token. Possible values are "+allowedWorkspaceRoleNamesProse)
106✔
376
        return cmd
106✔
377
}
378

379
//nolint:dupl
380
func newWorkspaceOrgTokenManageCmd(out io.Writer) *cobra.Command {
106✔
381
        cmd := &cobra.Command{
106✔
382
                Use:   "organization-token",
106✔
383
                Short: "Manage organization tokens in a workspace",
106✔
384
                Long:  "Manage organization tokens in a workspace",
106✔
385
        }
106✔
386
        cmd.SetOut(out)
106✔
387
        cmd.AddCommand(
106✔
388
                newAddOrganizationTokenWorkspaceRole(out),
106✔
389
                newUpdateOrganizationTokenWorkspaceRole(out),
106✔
390
                newRemoveOrganizationTokenWorkspaceRole(out),
106✔
391
                newListOrganizationTokensInWorkspace(out),
106✔
392
        )
106✔
393
        return cmd
106✔
394
}
106✔
395

396
func newAddOrganizationTokenWorkspaceRole(out io.Writer) *cobra.Command {
106✔
397
        cmd := &cobra.Command{
106✔
398
                Use:   "add [ORG_TOKEN_ID]",
106✔
399
                Short: "Add an Organization API token to a Workspace",
106✔
400
                Long:  "Add an Organization API token to a Workspace\n$astro workspace token organization-token add [ORG_TOKEN_ID] --org-token-name [token name] --role [" + allowedWorkspaceRoleNames + "].",
106✔
401
                RunE: func(cmd *cobra.Command, args []string) error {
108✔
402
                        return addOrgTokenWorkspaceRole(cmd, args, out)
2✔
403
                },
2✔
404
        }
405
        cmd.Flags().StringVarP(&orgTokenName, "org-token-name", "n", "", "The name of the Organization API token you want to add to a Workspace. If the name contains a space, specify the entire name within quotes \"\" ")
106✔
406
        cmd.Flags().StringVarP(&tokenRole, "role", "r", "", "The Workspace role to grant to the "+
106✔
407
                "Organization API token. Possible values are"+allowedWorkspaceRoleNamesProse)
106✔
408
        return cmd
106✔
409
}
410

411
func newUpdateOrganizationTokenWorkspaceRole(out io.Writer) *cobra.Command {
106✔
412
        cmd := &cobra.Command{
106✔
413
                Use:   "update [ORG_TOKEN_ID]",
106✔
414
                Short: "Update an Organization API token's Workspace Role",
106✔
415
                Long:  "Update an Organization API token's Workspace Role\n$astro workspace token organization-token update [ORG_TOKEN_ID] --org-token-name [token name] --role [" + allowedWorkspaceRoleNames + "].",
106✔
416
                RunE: func(cmd *cobra.Command, args []string) error {
108✔
417
                        return updateOrgTokenWorkspaceRole(cmd, args, out)
2✔
418
                },
2✔
419
        }
420
        cmd.Flags().StringVarP(&orgTokenName, "org-token-name", "n", "", "The name of the Organization API token you want to update in a Workspace. If the name contains a space, specify the entire name within quotes \"\" ")
106✔
421
        cmd.Flags().StringVarP(&tokenRole, "role", "r", "", "The Workspace role to update the "+
106✔
422
                "Organization API token. Possible values are"+allowedWorkspaceRoleNamesProse)
106✔
423
        return cmd
106✔
424
}
425

426
func addOrgTokenWorkspaceRole(cmd *cobra.Command, args []string, out io.Writer) error {
2✔
427
        // if an id was provided in the args we use it
2✔
428
        if len(args) > 0 {
3✔
429
                // make sure the id is lowercase
1✔
430
                orgTokenID = strings.ToLower(args[0])
1✔
431
        }
1✔
432
        if tokenRole == "" {
3✔
433
                // no role was provided so ask the user for it
1✔
434
                tokenRole = input.Text("Enter a role for the API token. Possible values are " + allowedWorkspaceRoleNamesProse + ": ")
1✔
435
        }
1✔
436
        cmd.SilenceUsage = true
2✔
437

2✔
438
        return workspacetoken.UpsertOrgTokenWorkspaceRole(orgTokenID, orgTokenName, tokenRole, workspaceID, "create", out, astroCoreClient, astroCoreIamClient)
2✔
439
}
440

441
func updateOrgTokenWorkspaceRole(cmd *cobra.Command, args []string, out io.Writer) error {
2✔
442
        // if an id was provided in the args we use it
2✔
443
        if len(args) > 0 {
3✔
444
                // make sure the id is lowercase
1✔
445
                orgTokenID = strings.ToLower(args[0])
1✔
446
        }
1✔
447
        if tokenRole == "" {
3✔
448
                // no role was provided so ask the user for it
1✔
449
                tokenRole = input.Text("Enter a role for the new Workspace API token. Possible values are " + allowedWorkspaceRoleNamesProse + ": ")
1✔
450
        }
1✔
451
        cmd.SilenceUsage = true
2✔
452

2✔
453
        return workspacetoken.UpsertOrgTokenWorkspaceRole(orgTokenID, orgTokenName, tokenRole, workspaceID, "update", out, astroCoreClient, astroCoreIamClient)
2✔
454
}
455

456
func newRemoveOrganizationTokenWorkspaceRole(out io.Writer) *cobra.Command {
106✔
457
        cmd := &cobra.Command{
106✔
458
                Use:   "remove [ORG_TOKEN_ID]",
106✔
459
                Short: "Remove an Organization API token's Workspace Role",
106✔
460
                Long:  "Remove an Organization API token's Workspace Role\n$astro workspace token organization-token remove [ORG_TOKEN_ID] --org-token-name [token name].",
106✔
461
                RunE: func(cmd *cobra.Command, args []string) error {
108✔
462
                        return removeOrganizationTokenWorkspaceRole(cmd, args, out)
2✔
463
                },
2✔
464
        }
465
        cmd.Flags().StringVarP(&orgTokenName, "org-token-name", "n", "", "The name of the Workspace API token you want to remove from a Deployment. If the name contains a space, specify the entire name within quotes \"\" ")
106✔
466
        return cmd
106✔
467
}
468

469
func removeOrganizationTokenWorkspaceRole(cmd *cobra.Command, args []string, out io.Writer) error {
2✔
470
        // if an id was provided in the args we use it
2✔
471
        if len(args) > 0 {
3✔
472
                // make sure the id is lowercase
1✔
473
                orgTokenID = strings.ToLower(args[0])
1✔
474
        }
1✔
475

476
        cmd.SilenceUsage = true
2✔
477
        return workspacetoken.RemoveOrgTokenWorkspaceRole(orgTokenID, orgTokenName, workspaceID, out, astroCoreClient, astroCoreIamClient)
2✔
478
}
479

480
func newListOrganizationTokensInWorkspace(out io.Writer) *cobra.Command {
106✔
481
        cmd := &cobra.Command{
106✔
482
                Use:   "list",
106✔
483
                Short: "List all Organization API tokens in a workspace",
106✔
484
                Long:  "List all Organization API tokens in a workspace\n$astro workspace token organization-token list",
106✔
485
                RunE: func(cmd *cobra.Command, args []string) error {
107✔
486
                        return listOrganizationTokensInWorkspace(cmd, out)
1✔
487
                },
1✔
488
        }
489
        return cmd
106✔
490
}
491

492
func listOrganizationTokensInWorkspace(cmd *cobra.Command, out io.Writer) error {
1✔
493
        cmd.SilenceUsage = true
1✔
494
        tokenTypes := []astrocore.ListWorkspaceApiTokensParamsTokenTypes{
1✔
495
                "ORGANIZATION",
1✔
496
        }
1✔
497
        return workspacetoken.ListTokens(astroCoreClient, deploymentID, &tokenTypes, out)
1✔
498
}
1✔
499

500
func newWorkspaceTeamRemoveCmd(out io.Writer) *cobra.Command {
106✔
501
        cmd := &cobra.Command{
106✔
502
                Use:     "remove",
106✔
503
                Aliases: []string{"rm"},
106✔
504
                Short:   "Remove a team from an Astro Workspace",
106✔
505
                Long:    "Remove a team from an Astro Workspace",
106✔
506
                RunE: func(cmd *cobra.Command, args []string) error {
110✔
507
                        return removeWorkspaceTeam(cmd, args, out)
4✔
508
                },
4✔
509
        }
510
        return cmd
106✔
511
}
512

513
func listWorkspaceTeam(cmd *cobra.Command, out io.Writer) error {
2✔
514
        cmd.SilenceUsage = true
2✔
515
        return team.ListWorkspaceTeams(out, astroCoreClient, "")
2✔
516
}
2✔
517

518
func removeWorkspaceTeam(cmd *cobra.Command, args []string, out io.Writer) error {
4✔
519
        var id string
4✔
520

4✔
521
        // if an id was provided in the args we use it
4✔
522
        if len(args) > 0 {
7✔
523
                // make sure the email is lowercase
3✔
524
                id = args[0]
3✔
525
        }
3✔
526
        cmd.SilenceUsage = true
4✔
527
        return team.RemoveWorkspaceTeam(id, "", out, astroCoreClient)
4✔
528
}
529

530
func newWorkspaceTeamAddCmd(out io.Writer) *cobra.Command {
106✔
531
        cmd := &cobra.Command{
106✔
532
                Use:   "add [id]",
106✔
533
                Short: "Add a team to an Astro Workspace with a specific role",
106✔
534
                Long:  "Add a team to an Astro Workspace with a specific role\n$astro workspace team add [id] --role [" + allowedWorkspaceRoleNames + "].",
106✔
535
                RunE: func(cmd *cobra.Command, args []string) error {
112✔
536
                        return addWorkspaceTeam(cmd, args, out)
6✔
537
                },
6✔
538
        }
539
        cmd.Flags().StringVarP(&workspaceID, "workspace-id", "w", "", "The Workspace's unique identifier")
106✔
540
        cmd.Flags().StringVarP(&addWorkspaceRole, "role", "r", "WORKSPACE_MEMBER", "The role for the "+
106✔
541
                "new team. Possible values are "+allowedWorkspaceRoleNamesProse)
106✔
542
        return cmd
106✔
543
}
544

545
func addWorkspaceTeam(cmd *cobra.Command, args []string, out io.Writer) error {
6✔
546
        var id string
6✔
547

6✔
548
        // if an email was provided in the args we use it
6✔
549
        if len(args) > 0 {
11✔
550
                // make sure the email is lowercase
5✔
551
                id = args[0]
5✔
552
        }
5✔
553
        cmd.SilenceUsage = true
6✔
554
        return team.AddWorkspaceTeam(id, addWorkspaceRole, workspaceID, out, astroCoreClient)
6✔
555
}
556

557
func newWorkspaceTeamUpdateCmd(out io.Writer) *cobra.Command {
106✔
558
        cmd := &cobra.Command{
106✔
559
                Use:     "update [id]",
106✔
560
                Aliases: []string{"up"},
106✔
561
                Short:   "Update a the role of a team in an Astro Workspace",
106✔
562
                Long:    "Update the role of a team in an Astro Workspace\n$astro workspace team update [id] --role [" + allowedWorkspaceRoleNames + "].",
106✔
563
                RunE: func(cmd *cobra.Command, args []string) error {
111✔
564
                        return updateWorkspaceTeam(cmd, args, out)
5✔
565
                },
5✔
566
        }
567
        cmd.Flags().StringVarP(&updateWorkspaceRole, "role", "r", "", "The new role for the "+
106✔
568
                "team. Possible values are "+allowedWorkspaceRoleNamesProse)
106✔
569
        return cmd
106✔
570
}
571

572
func updateWorkspaceTeam(cmd *cobra.Command, args []string, out io.Writer) error {
5✔
573
        var id string
5✔
574

5✔
575
        // if an id was provided in the args we use it
5✔
576
        if len(args) > 0 {
9✔
577
                id = args[0]
4✔
578
        }
4✔
579
        var err error
5✔
580
        if updateWorkspaceRole == "" {
5✔
UNCOV
581
                // no role was provided so ask the user for it
×
UNCOV
582
                updateWorkspaceRole, err = selectWorkspaceRole()
×
UNCOV
583
                if err != nil {
×
UNCOV
584
                        return err
×
UNCOV
585
                }
×
586
        }
587

588
        cmd.SilenceUsage = true
5✔
589
        return team.UpdateWorkspaceTeamRole(id, updateWorkspaceRole, "", out, astroCoreClient)
5✔
590
}
591

592
func workspaceList(cmd *cobra.Command, out io.Writer) error {
1✔
593
        // Silence Usage as we have now validated command input
1✔
594
        cmd.SilenceUsage = true
1✔
595
        return workspace.List(astroCoreClient, out)
1✔
596
}
1✔
597

598
func workspaceSwitch(cmd *cobra.Command, out io.Writer, args []string) error {
1✔
599
        // Silence Usage as we have now validated command input
1✔
600

1✔
601
        workspaceNameOrID := ""
1✔
602

1✔
603
        if len(args) == 1 {
1✔
UNCOV
604
                workspaceNameOrID = args[0]
×
UNCOV
605
        }
×
606
        cmd.SilenceUsage = true
1✔
607
        return workspace.Switch(workspaceNameOrID, astroCoreClient, out)
1✔
608
}
609

610
func workspaceCreate(cmd *cobra.Command, out io.Writer) error {
4✔
611
        cmd.SilenceUsage = true
4✔
612
        return workspace.Create(workspaceName, workspaceDescription, enforceCD, out, astroCoreClient)
4✔
613
}
4✔
614

615
func workspaceUpdate(cmd *cobra.Command, out io.Writer, args []string) error {
5✔
616
        id := ""
5✔
617

5✔
618
        if len(args) == 1 {
9✔
619
                id = args[0]
4✔
620
        }
4✔
621
        cmd.SilenceUsage = true
5✔
622
        return workspace.Update(id, workspaceName, workspaceDescription, enforceCD, out, astroCoreClient)
5✔
623
}
624

625
func workspaceDelete(cmd *cobra.Command, out io.Writer, args []string) error {
5✔
626
        id := ""
5✔
627

5✔
628
        if len(args) == 1 {
9✔
629
                id = args[0]
4✔
630
        }
4✔
631
        cmd.SilenceUsage = true
5✔
632
        return workspace.Delete(id, out, astroCoreClient)
5✔
633
}
634

635
func addWorkspaceUser(cmd *cobra.Command, args []string, out io.Writer) error {
5✔
636
        var email string
5✔
637

5✔
638
        // if an email was provided in the args we use it
5✔
639
        if len(args) > 0 {
9✔
640
                // make sure the email is lowercase
4✔
641
                email = strings.ToLower(args[0])
4✔
642
        }
4✔
643

644
        cmd.SilenceUsage = true
5✔
645
        return user.AddWorkspaceUser(email, addWorkspaceRole, workspaceID, out, astroCoreClient)
5✔
646
}
647

648
func listWorkspaceUser(cmd *cobra.Command, out io.Writer) error {
2✔
649
        cmd.SilenceUsage = true
2✔
650
        return user.ListWorkspaceUsers(out, astroCoreClient, workspaceID)
2✔
651
}
2✔
652

653
func updateWorkspaceUser(cmd *cobra.Command, args []string, out io.Writer) error {
5✔
654
        var email string
5✔
655

5✔
656
        // if an email was provided in the args we use it
5✔
657
        if len(args) > 0 {
9✔
658
                // make sure the email is lowercase
4✔
659
                email = strings.ToLower(args[0])
4✔
660
        }
4✔
661

662
        if updateWorkspaceRole == "" {
5✔
UNCOV
663
                // no role was provided so ask the user for it
×
UNCOV
664
                updateWorkspaceRole = input.Text("Enter a user Workspace role(" + allowedWorkspaceRoleNamesProse + ") to update user: ")
×
UNCOV
665
        }
×
666

667
        cmd.SilenceUsage = true
5✔
668
        return user.UpdateWorkspaceUserRole(email, updateWorkspaceRole, workspaceID, out, astroCoreClient)
5✔
669
}
670

671
func removeWorkspaceUser(cmd *cobra.Command, args []string, out io.Writer) error {
4✔
672
        var email string
4✔
673

4✔
674
        // if an email was provided in the args we use it
4✔
675
        if len(args) > 0 {
7✔
676
                // make sure the email is lowercase
3✔
677
                email = strings.ToLower(args[0])
3✔
678
        }
3✔
679

680
        cmd.SilenceUsage = true
4✔
681
        return user.RemoveWorkspaceUser(email, workspaceID, out, astroCoreClient)
4✔
682
}
683

684
func listWorkspaceToken(cmd *cobra.Command, out io.Writer) error {
4✔
685
        cmd.SilenceUsage = true
4✔
686
        return workspacetoken.ListTokens(astroCoreClient, workspaceID, nil, out)
4✔
687
}
4✔
688

689
func createWorkspaceToken(cmd *cobra.Command, out io.Writer) error {
4✔
690
        if tokenName == "" {
5✔
691
                // no role was provided so ask the user for it
1✔
692
                tokenName = input.Text("Enter a name for the new Workspace API token: ")
1✔
693
        }
1✔
694
        if tokenRole == "" {
5✔
695
                fmt.Println("select a Workspace Role for the new API token:")
1✔
696
                // no role was provided so ask the user for it
1✔
697
                var err error
1✔
698
                tokenRole, err = selectWorkspaceRole()
1✔
699
                if err != nil {
1✔
UNCOV
700
                        return err
×
UNCOV
701
                }
×
702
        }
703
        cmd.SilenceUsage = true
4✔
704

4✔
705
        return workspacetoken.CreateToken(tokenName, tokenDescription, tokenRole, workspaceID, tokenExpiration, cleanTokenOutput, out, astroCoreClient)
4✔
706
}
707

708
func updateWorkspaceToken(cmd *cobra.Command, args []string, out io.Writer) error {
4✔
709
        // if an id was provided in the args we use it
4✔
710
        if len(args) > 0 {
4✔
UNCOV
711
                // make sure the id is lowercase
×
UNCOV
712
                tokenID = strings.ToLower(args[0])
×
UNCOV
713
        }
×
714

715
        cmd.SilenceUsage = true
4✔
716
        return workspacetoken.UpdateToken(tokenID, name, tokenName, tokenDescription, tokenRole, workspaceID, out, astroCoreClient, astroCoreIamClient)
4✔
717
}
718

719
func rotateWorkspaceToken(cmd *cobra.Command, args []string, out io.Writer) error {
5✔
720
        // if an id was provided in the args we use it
5✔
721
        if len(args) > 0 {
5✔
UNCOV
722
                // make sure the id is lowercase
×
UNCOV
723
                tokenID = strings.ToLower(args[0])
×
UNCOV
724
        }
×
725
        cmd.SilenceUsage = true
5✔
726
        return workspacetoken.RotateToken(tokenID, name, workspaceID, cleanTokenOutput, forceRotate, out, astroCoreClient, astroCoreIamClient)
5✔
727
}
728

729
func deleteWorkspaceToken(cmd *cobra.Command, args []string, out io.Writer) error {
5✔
730
        // if an id was provided in the args we use it
5✔
731
        if len(args) > 0 {
5✔
UNCOV
732
                // make sure the id is lowercase
×
UNCOV
733
                tokenID = strings.ToLower(args[0])
×
UNCOV
734
        }
×
735

736
        cmd.SilenceUsage = true
5✔
737
        return workspacetoken.DeleteToken(tokenID, name, workspaceID, forceDelete, out, astroCoreClient, astroCoreIamClient)
5✔
738
}
739

740
func addOrgTokenToWorkspace(cmd *cobra.Command, args []string, out io.Writer) error {
5✔
741
        // if an id was provided in the args we use it
5✔
742
        if len(args) > 0 {
5✔
UNCOV
743
                // make sure the id is lowercase
×
UNCOV
744
                orgTokenID = strings.ToLower(args[0])
×
UNCOV
745
        }
×
746
        if tokenRole == "" {
6✔
747
                fmt.Println("select a Workspace Role for the Organization Token:")
1✔
748
                // no role was provided so ask the user for it
1✔
749
                var err error
1✔
750
                tokenRole, err = selectWorkspaceRole()
1✔
751
                if err != nil {
1✔
UNCOV
752
                        return err
×
UNCOV
753
                }
×
754
        }
755
        cmd.SilenceUsage = true
5✔
756
        return organization.AddOrgTokenToWorkspace(orgTokenID, orgTokenName, tokenRole, workspaceID, out, astroCoreClient, astroCoreIamClient)
5✔
757
}
758

759
func coalesceWorkspace() (string, error) {
137✔
760
        wsFlag := workspaceID
137✔
761
        wsCfg, err := workspace.GetCurrentWorkspace()
137✔
762
        if err != nil {
156✔
763
                return "", errors.Wrap(err, "failed to get current Workspace")
19✔
764
        }
19✔
765

766
        if wsFlag != "" {
145✔
767
                return wsFlag, nil
27✔
768
        }
27✔
769

770
        if wsCfg != "" {
182✔
771
                return wsCfg, nil
91✔
772
        }
91✔
773

UNCOV
774
        return "", errors.New("no valid Workspace source found")
×
775
}
776

777
func selectWorkspaceRole() (string, error) {
2✔
778
        tokenRolesMap := map[string]string{}
2✔
779
        tab := &printutil.Table{
2✔
780
                Padding:        []int{44, 50},
2✔
781
                DynamicPadding: true,
2✔
782
                Header:         []string{"#", "ROLE"},
2✔
783
        }
2✔
784
        for i := range validWorkspaceRoles {
10✔
785
                index := i + 1
8✔
786
                tab.AddRow([]string{
8✔
787
                        strconv.Itoa(index),
8✔
788
                        validWorkspaceRoles[i],
8✔
789
                }, false)
8✔
790
                tokenRolesMap[strconv.Itoa(index)] = validWorkspaceRoles[i]
8✔
791
        }
8✔
792

793
        tab.Print(os.Stdout)
2✔
794
        choice := input.Text("\n> ")
2✔
795
        selected, ok := tokenRolesMap[choice]
2✔
796
        if !ok {
2✔
UNCOV
797
                return "", errInvalidWorkspaceRoleKey
×
UNCOV
798
        }
×
799
        return selected, nil
2✔
800
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc