Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd232aa2

Browse files
committed
feat: addsharing show command to the CLI
1 parent909acbc commitd232aa2

File tree

3 files changed

+199
-2
lines changed

3 files changed

+199
-2
lines changed

‎cli/sharing.go‎

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cli
22

33
import (
4+
"context"
45
"fmt"
56
"regexp"
67

@@ -29,14 +30,52 @@ func (r *RootCmd) sharing() *serpent.Command {
2930
Handler:func(inv*serpent.Invocation)error {
3031
returninv.Command.HelpHandler(inv)
3132
},
32-
Children: []*serpent.Command{r.shareWorkspace(orgContext)},
33-
Hidden:true,
33+
Children: []*serpent.Command{
34+
r.shareWorkspace(orgContext),
35+
r.statusWorkspaceSharing(),
36+
},
37+
Hidden:true,
3438
}
3539

3640
orgContext.AttachOptions(cmd)
3741
returncmd
3842
}
3943

44+
func (r*RootCmd)statusWorkspaceSharing()*serpent.Command {
45+
client:=new(codersdk.Client)
46+
47+
cmd:=&serpent.Command{
48+
Use:"status <workspace>",
49+
Short:"List all users and groups the given Workspace is shared with.",
50+
Aliases: []string{"list"},
51+
Middleware:serpent.Chain(
52+
r.InitClient(client),
53+
serpent.RequireNArgs(1),
54+
),
55+
Handler:func(inv*serpent.Invocation)error {
56+
workspace,err:=namedWorkspace(inv.Context(),client,inv.Args[0])
57+
iferr!=nil {
58+
returnxerrors.Errorf("unable to fetch Workspace %s: %w",inv.Args[0],err)
59+
}
60+
61+
acl,err:=client.WorkspaceACL(inv.Context(),workspace.ID)
62+
iferr!=nil {
63+
returnxerrors.Errorf("unable to fetch ACL for Workspace: %w",err)
64+
}
65+
66+
out,err:=workspaceACLToTable(inv.Context(),&acl)
67+
iferr!=nil {
68+
returnerr
69+
}
70+
71+
_,err=fmt.Fprintln(inv.Stdout,out)
72+
returnerr
73+
},
74+
}
75+
76+
returncmd
77+
}
78+
4079
func (r*RootCmd)shareWorkspace(orgContext*OrganizationContext)*serpent.Command {
4180
var (
4281
// Username regex taken from codersdk/name.go
@@ -229,3 +268,48 @@ func stringToWorkspaceRole(role string) (codersdk.WorkspaceRole, error) {
229268
role,codersdk.WorkspaceRoleAdmin,codersdk.WorkspaceRoleUse)
230269
}
231270
}
271+
272+
funcworkspaceACLToTable(ctx context.Context,acl*codersdk.WorkspaceACL) (string,error) {
273+
typeworkspaceShareRowstruct {
274+
Userstring`table:"user"`
275+
Groupstring`table:"group,default_sort"`
276+
Role codersdk.WorkspaceRole`table:"role"`
277+
}
278+
279+
formatter:=cliui.NewOutputFormatter(
280+
cliui.TableFormat(
281+
[]workspaceShareRow{}, []string{"User","Group","Role"}),
282+
cliui.JSONFormat())
283+
284+
outputRows:=make([]workspaceShareRow,0)
285+
for_,user:=rangeacl.Users {
286+
ifuser.Role==codersdk.WorkspaceRoleDeleted {
287+
continue
288+
}
289+
290+
outputRows=append(outputRows,workspaceShareRow{
291+
User:user.Username,
292+
Group:defaultGroupDisplay,
293+
Role:user.Role,
294+
})
295+
}
296+
for_,group:=rangeacl.Groups {
297+
ifgroup.Role==codersdk.WorkspaceRoleDeleted {
298+
continue
299+
}
300+
301+
for_,user:=rangegroup.Members {
302+
outputRows=append(outputRows,workspaceShareRow{
303+
User:user.Username,
304+
Group:group.Name,
305+
Role:group.Role,
306+
})
307+
}
308+
}
309+
out,err:=formatter.Format(ctx,outputRows)
310+
iferr!=nil {
311+
return"",err
312+
}
313+
314+
returnout,nil
315+
}

‎cli/sharing_test.go‎

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,55 @@ func TestSharingShare(t *testing.T) {
168168
assert.True(t,found,fmt.Sprintf("expected to find the username %s and role %s in the command: %s",toShareWithUser.Username,codersdk.WorkspaceRoleAdmin,out.String()))
169169
})
170170
}
171+
172+
funcTestSharingStatus(t*testing.T) {
173+
t.Parallel()
174+
175+
dv:=coderdtest.DeploymentValues(t)
176+
dv.Experiments= []string{string(codersdk.ExperimentWorkspaceSharing)}
177+
178+
t.Run("ListSharedUsers",func(t*testing.T) {
179+
t.Parallel()
180+
181+
var (
182+
client,db=coderdtest.NewWithDatabase(t,&coderdtest.Options{
183+
DeploymentValues:dv,
184+
})
185+
orgOwner=coderdtest.CreateFirstUser(t,client)
186+
workspaceOwnerClient,workspaceOwner=coderdtest.CreateAnotherUser(t,client,orgOwner.OrganizationID,rbac.ScopedRoleOrgAuditor(orgOwner.OrganizationID))
187+
workspace=dbfake.WorkspaceBuild(t,db, database.WorkspaceTable{
188+
OwnerID:workspaceOwner.ID,
189+
OrganizationID:orgOwner.OrganizationID,
190+
}).Do().Workspace
191+
_,toShareWithUser=coderdtest.CreateAnotherUser(t,client,orgOwner.OrganizationID)
192+
ctx=testutil.Context(t,testutil.WaitMedium)
193+
)
194+
195+
err:=client.UpdateWorkspaceACL(ctx,workspace.ID, codersdk.UpdateWorkspaceACL{
196+
UserRoles:map[string]codersdk.WorkspaceRole{
197+
toShareWithUser.ID.String():codersdk.WorkspaceRoleUse,
198+
},
199+
})
200+
require.NoError(t,err)
201+
202+
inv,root:=clitest.New(t,"sharing","status",workspace.Name,"--org",orgOwner.OrganizationID.String())
203+
clitest.SetupConfig(t,workspaceOwnerClient,root)
204+
205+
out:=bytes.NewBuffer(nil)
206+
inv.Stdout=out
207+
err=inv.WithContext(ctx).Run()
208+
require.NoError(t,err)
209+
210+
found:=false
211+
for_,line:=rangestrings.Split(out.String(),"\n") {
212+
ifstrings.Contains(line,toShareWithUser.Username)&&strings.Contains(line,string(codersdk.WorkspaceRoleUse)) {
213+
found=true
214+
}
215+
216+
iffound {
217+
break
218+
}
219+
}
220+
assert.True(t,found,"expected to find username %s with role %s in the output: %s",toShareWithUser.Username,codersdk.WorkspaceRoleUse,out.String())
221+
})
222+
}

‎enterprise/cli/sharing_test.go‎

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,67 @@ func TestSharingShareEnterprise(t *testing.T) {
187187
})
188188
}
189189

190+
funcTestSharingStatus(t*testing.T) {
191+
t.Parallel()
192+
193+
dv:=coderdtest.DeploymentValues(t)
194+
dv.Experiments= []string{string(codersdk.ExperimentWorkspaceSharing)}
195+
196+
t.Run("ListSharedUsers",func(t*testing.T) {
197+
t.Parallel()
198+
199+
var (
200+
client,db,orgOwner=coderdenttest.NewWithDatabase(t,&coderdenttest.Options{
201+
Options:&coderdtest.Options{
202+
DeploymentValues:dv,
203+
},
204+
LicenseOptions:&coderdenttest.LicenseOptions{
205+
Features: license.Features{
206+
codersdk.FeatureTemplateRBAC:1,
207+
},
208+
},
209+
})
210+
workspaceOwnerClient,workspaceOwner=coderdtest.CreateAnotherUser(t,client,orgOwner.OrganizationID,rbac.ScopedRoleOrgAuditor(orgOwner.OrganizationID))
211+
workspace=dbfake.WorkspaceBuild(t,db, database.WorkspaceTable{
212+
OwnerID:workspaceOwner.ID,
213+
OrganizationID:orgOwner.OrganizationID,
214+
}).Do().Workspace
215+
_,orgMember=coderdtest.CreateAnotherUser(t,client,orgOwner.OrganizationID)
216+
ctx=testutil.Context(t,testutil.WaitMedium)
217+
)
218+
219+
group,err:=createGroupWithMembers(ctx,client,orgOwner.OrganizationID,"new-group", []uuid.UUID{orgMember.ID})
220+
require.NoError(t,err)
221+
222+
err=client.UpdateWorkspaceACL(ctx,workspace.ID, codersdk.UpdateWorkspaceACL{
223+
GroupRoles:map[string]codersdk.WorkspaceRole{
224+
group.ID.String():codersdk.WorkspaceRoleUse,
225+
},
226+
})
227+
require.NoError(t,err)
228+
229+
inv,root:=clitest.New(t,"sharing","status",workspace.Name,"--org",orgOwner.OrganizationID.String())
230+
clitest.SetupConfig(t,workspaceOwnerClient,root)
231+
232+
out:=bytes.NewBuffer(nil)
233+
inv.Stdout=out
234+
err=inv.WithContext(ctx).Run()
235+
require.NoError(t,err)
236+
237+
found:=false
238+
for_,line:=rangestrings.Split(out.String(),"\n") {
239+
ifstrings.Contains(line,orgMember.Username)&&strings.Contains(line,string(codersdk.WorkspaceRoleUse))&&strings.Contains(line,group.Name) {
240+
found=true
241+
}
242+
243+
iffound {
244+
break
245+
}
246+
}
247+
assert.True(t,found,"expected to find username %s with role %s in the output: %s",orgMember.Username,codersdk.WorkspaceRoleUse,out.String())
248+
})
249+
}
250+
190251
funccreateGroupWithMembers(ctx context.Context,client*codersdk.Client,orgID uuid.UUID,namestring,memberIDs []uuid.UUID) (codersdk.Group,error) {
191252
group,err:=client.CreateGroup(ctx,orgID, codersdk.CreateGroupRequest{
192253
Name:name,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp