chore: include custom roles in list org roles (#13336)

* chore: include custom roles in list org roles
* move cli show roles to org scope
This commit is contained in:
Steven Masley
2024-05-23 07:54:59 -10:00
committed by GitHub
parent d748c6d718
commit 1b4ca00428
24 changed files with 312 additions and 117 deletions
+1
View File
@@ -30,6 +30,7 @@ func (r *RootCmd) organizations() *serpent.Command {
r.currentOrganization(),
r.switchOrganization(),
r.createOrganization(),
r.organizationRoles(),
},
}
+113
View File
@@ -0,0 +1,113 @@
package cli
import (
"fmt"
"slices"
"strings"
"golang.org/x/xerrors"
"github.com/coder/coder/v2/cli/cliui"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/serpent"
)
func (r *RootCmd) organizationRoles() *serpent.Command {
cmd := &serpent.Command{
Use: "roles",
Short: "Manage organization roles.",
Aliases: []string{"role"},
Handler: func(inv *serpent.Invocation) error {
return inv.Command.HelpHandler(inv)
},
Hidden: true,
Children: []*serpent.Command{
r.showOrganizationRoles(),
},
}
return cmd
}
func (r *RootCmd) showOrganizationRoles() *serpent.Command {
formatter := cliui.NewOutputFormatter(
cliui.ChangeFormatterData(
cliui.TableFormat([]assignableRolesTableRow{}, []string{"name", "display_name", "built_in", "site_permissions", "org_permissions", "user_permissions"}),
func(data any) (any, error) {
input, ok := data.([]codersdk.AssignableRoles)
if !ok {
return nil, xerrors.Errorf("expected []codersdk.AssignableRoles got %T", data)
}
rows := make([]assignableRolesTableRow, 0, len(input))
for _, role := range input {
rows = append(rows, assignableRolesTableRow{
Name: role.Name,
DisplayName: role.DisplayName,
SitePermissions: fmt.Sprintf("%d permissions", len(role.SitePermissions)),
OrganizationPermissions: fmt.Sprintf("%d organizations", len(role.OrganizationPermissions)),
UserPermissions: fmt.Sprintf("%d permissions", len(role.UserPermissions)),
Assignable: role.Assignable,
BuiltIn: role.BuiltIn,
})
}
return rows, nil
},
),
cliui.JSONFormat(),
)
client := new(codersdk.Client)
cmd := &serpent.Command{
Use: "show [role_names ...]",
Short: "Show role(s)",
Middleware: serpent.Chain(
r.InitClient(client),
),
Handler: func(inv *serpent.Invocation) error {
ctx := inv.Context()
org, err := CurrentOrganization(r, inv, client)
if err != nil {
return err
}
roles, err := client.ListOrganizationRoles(ctx, org.ID)
if err != nil {
return xerrors.Errorf("listing roles: %w", err)
}
if len(inv.Args) > 0 {
// filter roles
filtered := make([]codersdk.AssignableRoles, 0)
for _, role := range roles {
if slices.ContainsFunc(inv.Args, func(s string) bool {
return strings.EqualFold(s, role.Name)
}) {
filtered = append(filtered, role)
}
}
roles = filtered
}
out, err := formatter.Format(inv.Context(), roles)
if err != nil {
return err
}
_, err = fmt.Fprintln(inv.Stdout, out)
return err
},
}
formatter.AttachOptions(&cmd.Options)
return cmd
}
type assignableRolesTableRow struct {
Name string `table:"name,default_sort"`
DisplayName string `table:"display_name"`
SitePermissions string ` table:"site_permissions"`
// map[<org_id>] -> Permissions
OrganizationPermissions string `table:"org_permissions"`
UserPermissions string `table:"user_permissions"`
Assignable bool `table:"assignable"`
BuiltIn bool `table:"built_in"`
}
+51
View File
@@ -0,0 +1,51 @@
package cli_test
import (
"bytes"
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/cli/clitest"
"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/testutil"
)
func TestShowOrganizationRoles(t *testing.T) {
t.Parallel()
t.Run("OK", func(t *testing.T) {
t.Parallel()
ownerClient, db := coderdtest.NewWithDatabase(t, &coderdtest.Options{})
owner := coderdtest.CreateFirstUser(t, ownerClient)
client, _ := coderdtest.CreateAnotherUser(t, ownerClient, owner.OrganizationID, rbac.RoleUserAdmin())
const expectedRole = "test-role"
dbgen.CustomRole(t, db, database.CustomRole{
Name: expectedRole,
DisplayName: "Expected",
SitePermissions: nil,
OrgPermissions: nil,
UserPermissions: nil,
OrganizationID: uuid.NullUUID{
UUID: owner.OrganizationID,
Valid: true,
},
})
ctx := testutil.Context(t, testutil.WaitMedium)
inv, root := clitest.New(t, "organization", "roles", "show")
clitest.SetupConfig(t, client, root)
buf := new(bytes.Buffer)
inv.Stdout = buf
err := inv.WithContext(ctx).Run()
require.NoError(t, err)
require.Contains(t, buf.String(), expectedRole)
})
}