mirror of
https://github.com/coder/coder.git
synced 2025-03-14 10:09:57 +00:00
181 lines
3.8 KiB
Go
181 lines
3.8 KiB
Go
package cli
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/jedib0t/go-pretty/v6/table"
|
|
"golang.org/x/xerrors"
|
|
|
|
"github.com/coder/coder/v2/cli/cliui"
|
|
"github.com/coder/coder/v2/codersdk"
|
|
"github.com/coder/serpent"
|
|
)
|
|
|
|
func (r *RootCmd) userList() *serpent.Command {
|
|
formatter := cliui.NewOutputFormatter(
|
|
cliui.TableFormat([]codersdk.User{}, []string{"username", "email", "created at", "status"}),
|
|
cliui.JSONFormat(),
|
|
)
|
|
client := new(codersdk.Client)
|
|
|
|
cmd := &serpent.Command{
|
|
Use: "list",
|
|
Aliases: []string{"ls"},
|
|
Middleware: serpent.Chain(
|
|
serpent.RequireNArgs(0),
|
|
r.InitClient(client),
|
|
),
|
|
Handler: func(inv *serpent.Invocation) error {
|
|
res, err := client.Users(inv.Context(), codersdk.UsersRequest{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
out, err := formatter.Format(inv.Context(), res.Users)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = fmt.Fprintln(inv.Stdout, out)
|
|
return err
|
|
},
|
|
}
|
|
|
|
formatter.AttachOptions(&cmd.Options)
|
|
return cmd
|
|
}
|
|
|
|
func (r *RootCmd) userSingle() *serpent.Command {
|
|
formatter := cliui.NewOutputFormatter(
|
|
&userShowFormat{},
|
|
cliui.JSONFormat(),
|
|
)
|
|
client := new(codersdk.Client)
|
|
|
|
cmd := &serpent.Command{
|
|
Use: "show <username|user_id|'me'>",
|
|
Short: "Show a single user. Use 'me' to indicate the currently authenticated user.",
|
|
Long: FormatExamples(
|
|
Example{
|
|
Command: "coder users show me",
|
|
},
|
|
),
|
|
Middleware: serpent.Chain(
|
|
serpent.RequireNArgs(1),
|
|
r.InitClient(client),
|
|
),
|
|
Handler: func(inv *serpent.Invocation) error {
|
|
user, err := client.User(inv.Context(), inv.Args[0])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
orgNames := make([]string, len(user.OrganizationIDs))
|
|
for i, orgID := range user.OrganizationIDs {
|
|
org, err := client.Organization(inv.Context(), orgID)
|
|
if err != nil {
|
|
return xerrors.Errorf("get organization %q: %w", orgID.String(), err)
|
|
}
|
|
|
|
orgNames[i] = org.Name
|
|
}
|
|
|
|
out, err := formatter.Format(inv.Context(), userWithOrgNames{
|
|
User: user,
|
|
OrganizationNames: orgNames,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = fmt.Fprintln(inv.Stdout, out)
|
|
return err
|
|
},
|
|
}
|
|
|
|
formatter.AttachOptions(&cmd.Options)
|
|
return cmd
|
|
}
|
|
|
|
type userWithOrgNames struct {
|
|
codersdk.User
|
|
OrganizationNames []string `json:"organization_names"`
|
|
}
|
|
|
|
type userShowFormat struct{}
|
|
|
|
var _ cliui.OutputFormat = &userShowFormat{}
|
|
|
|
// ID implements OutputFormat.
|
|
func (*userShowFormat) ID() string {
|
|
return "table"
|
|
}
|
|
|
|
// AttachOptions implements OutputFormat.
|
|
func (*userShowFormat) AttachOptions(_ *serpent.OptionSet) {}
|
|
|
|
// Format implements OutputFormat.
|
|
func (*userShowFormat) Format(_ context.Context, out interface{}) (string, error) {
|
|
user, ok := out.(userWithOrgNames)
|
|
if !ok {
|
|
return "", xerrors.Errorf("expected type %T, got %T", user, out)
|
|
}
|
|
|
|
tw := cliui.Table()
|
|
addRow := func(name string, value interface{}) {
|
|
key := ""
|
|
if name != "" {
|
|
key = name + ":"
|
|
}
|
|
tw.AppendRow(table.Row{
|
|
key, value,
|
|
})
|
|
}
|
|
|
|
// Add rows for each of the user's fields.
|
|
addRow("ID", user.ID.String())
|
|
addRow("Username", user.Username)
|
|
addRow("Full name", user.Name)
|
|
addRow("Email", user.Email)
|
|
addRow("Status", user.Status)
|
|
addRow("Created At", user.CreatedAt.Format(time.Stamp))
|
|
|
|
addRow("", "")
|
|
firstRole := true
|
|
for _, role := range user.Roles {
|
|
if role.DisplayName == "" {
|
|
// Skip roles with no display name.
|
|
continue
|
|
}
|
|
|
|
key := ""
|
|
if firstRole {
|
|
key = "Roles"
|
|
firstRole = false
|
|
}
|
|
addRow(key, role.DisplayName)
|
|
}
|
|
if firstRole {
|
|
addRow("Roles", "(none)")
|
|
}
|
|
|
|
addRow("", "")
|
|
firstOrg := true
|
|
for _, orgName := range user.OrganizationNames {
|
|
key := ""
|
|
if firstOrg {
|
|
key = "Organizations"
|
|
firstOrg = false
|
|
}
|
|
|
|
addRow(key, orgName)
|
|
}
|
|
if firstOrg {
|
|
addRow("Organizations", "(none)")
|
|
}
|
|
|
|
return tw.Render(), nil
|
|
}
|