mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
chore: refactor to directly create Client in Command Handlers (#19760)
Refactors the CLI to create the `*codersdk.Client` in the handlers. This is groundwork for changing the `rootCmd.InitClient()` to use the new `ClientOption`s. It also improves variable locality, scoping the Client to the handler. This makes misuse less likely and reduces the memory allocations to just the command being executed, rather than allocating a Client for every command regardless of whether it is executed.
This commit is contained in:
+6
-3
@@ -12,18 +12,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) autoupdate() *serpent.Command {
|
func (r *RootCmd) autoupdate() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "autoupdate <workspace> <always|never>",
|
Use: "autoupdate <workspace> <always|never>",
|
||||||
Short: "Toggle auto-update policy for a workspace",
|
Short: "Toggle auto-update policy for a workspace",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(2),
|
serpent.RequireNArgs(2),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
policy := strings.ToLower(inv.Args[1])
|
policy := strings.ToLower(inv.Args[1])
|
||||||
err := validateAutoUpdatePolicy(policy)
|
err = validateAutoUpdatePolicy(policy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("validate policy: %w", err)
|
return xerrors.Errorf("validate policy: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-3
@@ -236,7 +236,6 @@ func (r *RootCmd) configSSH() *serpent.Command {
|
|||||||
dryRun bool
|
dryRun bool
|
||||||
coderCliPath string
|
coderCliPath string
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "config-ssh",
|
Use: "config-ssh",
|
||||||
@@ -253,9 +252,13 @@ func (r *RootCmd) configSSH() *serpent.Command {
|
|||||||
),
|
),
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
|
||||||
if sshConfigOpts.waitEnum != "auto" && sshConfigOpts.skipProxyCommand {
|
if sshConfigOpts.waitEnum != "auto" && sshConfigOpts.skipProxyCommand {
|
||||||
@@ -280,7 +283,6 @@ func (r *RootCmd) configSSH() *serpent.Command {
|
|||||||
out = inv.Stderr
|
out = inv.Stderr
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
|
||||||
coderBinary := coderCliPath
|
coderBinary := coderCliPath
|
||||||
if coderBinary == "" {
|
if coderBinary == "" {
|
||||||
coderBinary, err = currentBinPath(out)
|
coderBinary, err = currentBinPath(out)
|
||||||
|
|||||||
+5
-3
@@ -50,7 +50,6 @@ func (r *RootCmd) Create(opts CreateOptions) *serpent.Command {
|
|||||||
// shares the same name across multiple organizations.
|
// shares the same name across multiple organizations.
|
||||||
orgContext = NewOrganizationContext()
|
orgContext = NewOrganizationContext()
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "create [workspace]",
|
Use: "create [workspace]",
|
||||||
@@ -61,9 +60,12 @@ func (r *RootCmd) Create(opts CreateOptions) *serpent.Command {
|
|||||||
Command: "coder create <username>/<workspace_name>",
|
Command: "coder create <username>/<workspace_name>",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Middleware: serpent.Chain(r.InitClient(client)),
|
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
var err error
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
workspaceOwner := codersdk.Me
|
workspaceOwner := codersdk.Me
|
||||||
if len(inv.Args) >= 1 {
|
if len(inv.Args) >= 1 {
|
||||||
workspaceOwner, workspaceName, err = splitNamedWorkspace(inv.Args[0])
|
workspaceOwner, workspaceName, err = splitNamedWorkspace(inv.Args[0])
|
||||||
|
|||||||
+5
-2
@@ -16,7 +16,6 @@ func (r *RootCmd) deleteWorkspace() *serpent.Command {
|
|||||||
orphan bool
|
orphan bool
|
||||||
prov buildFlags
|
prov buildFlags
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "delete <workspace>",
|
Use: "delete <workspace>",
|
||||||
@@ -29,9 +28,13 @@ func (r *RootCmd) deleteWorkspace() *serpent.Command {
|
|||||||
),
|
),
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
+5
-4
@@ -399,7 +399,6 @@ type mcpServer struct {
|
|||||||
|
|
||||||
func (r *RootCmd) mcpServer() *serpent.Command {
|
func (r *RootCmd) mcpServer() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
client = new(codersdk.Client)
|
|
||||||
instructions string
|
instructions string
|
||||||
allowedTools []string
|
allowedTools []string
|
||||||
appStatusSlug string
|
appStatusSlug string
|
||||||
@@ -409,6 +408,11 @@ func (r *RootCmd) mcpServer() *serpent.Command {
|
|||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "server",
|
Use: "server",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.TryInitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
var lastReport taskReport
|
var lastReport taskReport
|
||||||
// Create a queue that skips duplicates and preserves summaries.
|
// Create a queue that skips duplicates and preserves summaries.
|
||||||
queue := cliutil.NewQueue[taskReport](512).WithPredicate(func(report taskReport) (taskReport, bool) {
|
queue := cliutil.NewQueue[taskReport](512).WithPredicate(func(report taskReport) (taskReport, bool) {
|
||||||
@@ -548,9 +552,6 @@ func (r *RootCmd) mcpServer() *serpent.Command {
|
|||||||
return srv.startServer(ctx, inv, instructions, allowedTools)
|
return srv.startServer(ctx, inv, instructions, allowedTools)
|
||||||
},
|
},
|
||||||
Short: "Start the Coder MCP server.",
|
Short: "Start the Coder MCP server.",
|
||||||
Middleware: serpent.Chain(
|
|
||||||
r.TryInitClient(client),
|
|
||||||
),
|
|
||||||
Options: []serpent.Option{
|
Options: []serpent.Option{
|
||||||
{
|
{
|
||||||
Name: "instructions",
|
Name: "instructions",
|
||||||
|
|||||||
+5
-5
@@ -22,16 +22,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) rptyCommand() *serpent.Command {
|
func (r *RootCmd) rptyCommand() *serpent.Command {
|
||||||
var (
|
var args handleRPTYArgs
|
||||||
client = new(codersdk.Client)
|
|
||||||
args handleRPTYArgs
|
|
||||||
)
|
|
||||||
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
if r.disableDirect {
|
if r.disableDirect {
|
||||||
return xerrors.New("direct connections are disabled, but you can try websocat ;-)")
|
return xerrors.New("direct connections are disabled, but you can try websocat ;-)")
|
||||||
}
|
}
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
args.NamedWorkspace = inv.Args[0]
|
args.NamedWorkspace = inv.Args[0]
|
||||||
args.Command = inv.Args[1:]
|
args.Command = inv.Args[1:]
|
||||||
return handleRPTY(inv, client, args)
|
return handleRPTY(inv, client, args)
|
||||||
@@ -39,7 +40,6 @@ func (r *RootCmd) rptyCommand() *serpent.Command {
|
|||||||
Long: "Establish an RPTY session with a workspace/agent. This uses the same mechanism as the Web Terminal.",
|
Long: "Establish an RPTY session with a workspace/agent. This uses the same mechanism as the Web Terminal.",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireRangeArgs(1, -1),
|
serpent.RequireRangeArgs(1, -1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Options: []serpent.Option{
|
Options: []serpent.Option{
|
||||||
{
|
{
|
||||||
|
|||||||
+28
-26
@@ -395,18 +395,17 @@ func (r *userCleanupRunner) Run(ctx context.Context, _ string, _ io.Writer) erro
|
|||||||
|
|
||||||
func (r *RootCmd) scaletestCleanup() *serpent.Command {
|
func (r *RootCmd) scaletestCleanup() *serpent.Command {
|
||||||
var template string
|
var template string
|
||||||
|
|
||||||
cleanupStrategy := &scaletestStrategyFlags{cleanup: true}
|
cleanupStrategy := &scaletestStrategyFlags{cleanup: true}
|
||||||
client := new(codersdk.Client)
|
|
||||||
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "cleanup",
|
Use: "cleanup",
|
||||||
Short: "Cleanup scaletest workspaces, then cleanup scaletest users.",
|
Short: "Cleanup scaletest workspaces, then cleanup scaletest users.",
|
||||||
Long: "The strategy flags will apply to each stage of the cleanup process.",
|
Long: "The strategy flags will apply to each stage of the cleanup process.",
|
||||||
Middleware: serpent.Chain(
|
|
||||||
r.InitClient(client),
|
|
||||||
),
|
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
|
||||||
me, err := requireAdmin(ctx, client)
|
me, err := requireAdmin(ctx, client)
|
||||||
@@ -551,14 +550,16 @@ func (r *RootCmd) scaletestCreateWorkspaces() *serpent.Command {
|
|||||||
output = &scaletestOutputFlags{}
|
output = &scaletestOutputFlags{}
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "create-workspaces",
|
Use: "create-workspaces",
|
||||||
Short: "Creates many users, then creates a workspace for each user and waits for them finish building and fully come online. Optionally runs a command inside each workspace, and connects to the workspace over WireGuard.",
|
Short: "Creates many users, then creates a workspace for each user and waits for them finish building and fully come online. Optionally runs a command inside each workspace, and connects to the workspace over WireGuard.",
|
||||||
Long: `It is recommended that all rate limits are disabled on the server before running this scaletest. This test generates many login events which will be rate limited against the (most likely single) IP.`,
|
Long: `It is recommended that all rate limits are disabled on the server before running this scaletest. This test generates many login events which will be rate limited against the (most likely single) IP.`,
|
||||||
Middleware: r.InitClient(client),
|
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
|
||||||
me, err := requireAdmin(ctx, client)
|
me, err := requireAdmin(ctx, client)
|
||||||
@@ -861,7 +862,6 @@ func (r *RootCmd) scaletestWorkspaceTraffic() *serpent.Command {
|
|||||||
targetWorkspaces string
|
targetWorkspaces string
|
||||||
workspaceProxyURL string
|
workspaceProxyURL string
|
||||||
|
|
||||||
client = &codersdk.Client{}
|
|
||||||
tracingFlags = &scaletestTracingFlags{}
|
tracingFlags = &scaletestTracingFlags{}
|
||||||
strategy = &scaletestStrategyFlags{}
|
strategy = &scaletestStrategyFlags{}
|
||||||
cleanupStrategy = &scaletestStrategyFlags{cleanup: true}
|
cleanupStrategy = &scaletestStrategyFlags{cleanup: true}
|
||||||
@@ -872,10 +872,12 @@ func (r *RootCmd) scaletestWorkspaceTraffic() *serpent.Command {
|
|||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "workspace-traffic",
|
Use: "workspace-traffic",
|
||||||
Short: "Generate traffic to scaletest workspaces through coderd",
|
Short: "Generate traffic to scaletest workspaces through coderd",
|
||||||
Middleware: serpent.Chain(
|
|
||||||
r.InitClient(client),
|
|
||||||
),
|
|
||||||
Handler: func(inv *serpent.Invocation) (err error) {
|
Handler: func(inv *serpent.Invocation) (err error) {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
|
||||||
notifyCtx, stop := signal.NotifyContext(ctx, StopSignals...) // Checked later.
|
notifyCtx, stop := signal.NotifyContext(ctx, StopSignals...) // Checked later.
|
||||||
@@ -1150,13 +1152,11 @@ func (r *RootCmd) scaletestWorkspaceTraffic() *serpent.Command {
|
|||||||
|
|
||||||
func (r *RootCmd) scaletestDashboard() *serpent.Command {
|
func (r *RootCmd) scaletestDashboard() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
interval time.Duration
|
interval time.Duration
|
||||||
jitter time.Duration
|
jitter time.Duration
|
||||||
headless bool
|
headless bool
|
||||||
randSeed int64
|
randSeed int64
|
||||||
targetUsers string
|
targetUsers string
|
||||||
|
|
||||||
client = &codersdk.Client{}
|
|
||||||
tracingFlags = &scaletestTracingFlags{}
|
tracingFlags = &scaletestTracingFlags{}
|
||||||
strategy = &scaletestStrategyFlags{}
|
strategy = &scaletestStrategyFlags{}
|
||||||
cleanupStrategy = &scaletestStrategyFlags{cleanup: true}
|
cleanupStrategy = &scaletestStrategyFlags{cleanup: true}
|
||||||
@@ -1167,10 +1167,12 @@ func (r *RootCmd) scaletestDashboard() *serpent.Command {
|
|||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "dashboard",
|
Use: "dashboard",
|
||||||
Short: "Generate traffic to the HTTP API to simulate use of the dashboard.",
|
Short: "Generate traffic to the HTTP API to simulate use of the dashboard.",
|
||||||
Middleware: serpent.Chain(
|
|
||||||
r.InitClient(client),
|
|
||||||
),
|
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if !(interval > 0) {
|
if !(interval > 0) {
|
||||||
return xerrors.Errorf("--interval must be greater than zero")
|
return xerrors.Errorf("--interval must be greater than zero")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import (
|
|||||||
func (r *RootCmd) taskCreate() *serpent.Command {
|
func (r *RootCmd) taskCreate() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
orgContext = NewOrganizationContext()
|
orgContext = NewOrganizationContext()
|
||||||
client = new(codersdk.Client)
|
|
||||||
|
|
||||||
templateName string
|
templateName string
|
||||||
templateVersionName string
|
templateVersionName string
|
||||||
@@ -30,7 +29,6 @@ func (r *RootCmd) taskCreate() *serpent.Command {
|
|||||||
Short: "Create an experimental task",
|
Short: "Create an experimental task",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireRangeArgs(0, 1),
|
serpent.RequireRangeArgs(0, 1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Options: serpent.OptionSet{
|
Options: serpent.OptionSet{
|
||||||
{
|
{
|
||||||
@@ -67,6 +65,11 @@ func (r *RootCmd) taskCreate() *serpent.Command {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ctx = inv.Context()
|
ctx = inv.Context()
|
||||||
expClient = codersdk.NewExperimentalClient(client)
|
expClient = codersdk.NewExperimentalClient(client)
|
||||||
|
|||||||
@@ -16,20 +16,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) taskDelete() *serpent.Command {
|
func (r *RootCmd) taskDelete() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "delete <task> [<task> ...]",
|
Use: "delete <task> [<task> ...]",
|
||||||
Short: "Delete experimental tasks",
|
Short: "Delete experimental tasks",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireRangeArgs(1, -1),
|
serpent.RequireRangeArgs(1, -1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Options: serpent.OptionSet{
|
Options: serpent.OptionSet{
|
||||||
cliui.SkipPromptOption(),
|
cliui.SkipPromptOption(),
|
||||||
},
|
},
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
exp := codersdk.NewExperimentalClient(client)
|
exp := codersdk.NewExperimentalClient(client)
|
||||||
|
|
||||||
type toDelete struct {
|
type toDelete struct {
|
||||||
@@ -70,7 +71,7 @@ func (r *RootCmd) taskDelete() *serpent.Command {
|
|||||||
for _, it := range items {
|
for _, it := range items {
|
||||||
displayList = append(displayList, it.Display)
|
displayList = append(displayList, it.Display)
|
||||||
}
|
}
|
||||||
_, err := cliui.Prompt(inv, cliui.PromptOptions{
|
_, err = cliui.Prompt(inv, cliui.PromptOptions{
|
||||||
Text: fmt.Sprintf("Delete these tasks: %s?", pretty.Sprint(cliui.DefaultStyles.Code, strings.Join(displayList, ", "))),
|
Text: fmt.Sprintf("Delete these tasks: %s?", pretty.Sprint(cliui.DefaultStyles.Code, strings.Join(displayList, ", "))),
|
||||||
IsConfirm: true,
|
IsConfirm: true,
|
||||||
Default: cliui.ConfirmNo,
|
Default: cliui.ConfirmNo,
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ func (r *RootCmd) taskList() *serpent.Command {
|
|||||||
user string
|
user string
|
||||||
quiet bool
|
quiet bool
|
||||||
|
|
||||||
client = new(codersdk.Client)
|
|
||||||
formatter = cliui.NewOutputFormatter(
|
formatter = cliui.NewOutputFormatter(
|
||||||
cliui.TableFormat(
|
cliui.TableFormat(
|
||||||
[]taskListRow{},
|
[]taskListRow{},
|
||||||
@@ -73,7 +72,6 @@ func (r *RootCmd) taskList() *serpent.Command {
|
|||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Options: serpent.OptionSet{
|
Options: serpent.OptionSet{
|
||||||
{
|
{
|
||||||
@@ -108,6 +106,11 @@ func (r *RootCmd) taskList() *serpent.Command {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
exp := codersdk.NewExperimentalClient(client)
|
exp := codersdk.NewExperimentalClient(client)
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import (
|
|||||||
|
|
||||||
func (r *RootCmd) taskStatus() *serpent.Command {
|
func (r *RootCmd) taskStatus() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
client = new(codersdk.Client)
|
|
||||||
formatter = cliui.NewOutputFormatter(
|
formatter = cliui.NewOutputFormatter(
|
||||||
cliui.TableFormat(
|
cliui.TableFormat(
|
||||||
[]taskStatusRow{},
|
[]taskStatusRow{},
|
||||||
@@ -66,9 +65,13 @@ func (r *RootCmd) taskStatus() *serpent.Command {
|
|||||||
},
|
},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(i *serpent.Invocation) error {
|
Handler: func(i *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(i)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ctx := i.Context()
|
ctx := i.Context()
|
||||||
ec := codersdk.NewExperimentalClient(client)
|
ec := codersdk.NewExperimentalClient(client)
|
||||||
identifier := i.Args[0]
|
identifier := i.Args[0]
|
||||||
|
|||||||
+10
-5
@@ -5,12 +5,10 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/coder/coder/v2/codersdk"
|
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) favorite() *serpent.Command {
|
func (r *RootCmd) favorite() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Aliases: []string{"fav", "favou" + "rite"},
|
Aliases: []string{"fav", "favou" + "rite"},
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
@@ -18,9 +16,13 @@ func (r *RootCmd) favorite() *serpent.Command {
|
|||||||
Short: "Add a workspace to your favorites",
|
Short: "Add a workspace to your favorites",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ws, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
ws, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("get workspace: %w", err)
|
return xerrors.Errorf("get workspace: %w", err)
|
||||||
@@ -37,7 +39,6 @@ func (r *RootCmd) favorite() *serpent.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) unfavorite() *serpent.Command {
|
func (r *RootCmd) unfavorite() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Aliases: []string{"unfav", "unfavou" + "rite"},
|
Aliases: []string{"unfav", "unfavou" + "rite"},
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
@@ -45,9 +46,13 @@ func (r *RootCmd) unfavorite() *serpent.Command {
|
|||||||
Short: "Remove a workspace from your favorites",
|
Short: "Remove a workspace from your favorites",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ws, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
ws, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("get workspace: %w", err)
|
return xerrors.Errorf("get workspace: %w", err)
|
||||||
|
|||||||
+5
-2
@@ -96,7 +96,6 @@ func (r *RootCmd) list() *serpent.Command {
|
|||||||
cliui.JSONFormat(),
|
cliui.JSONFormat(),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "list",
|
Use: "list",
|
||||||
@@ -104,9 +103,13 @@ func (r *RootCmd) list() *serpent.Command {
|
|||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
res, err := QueryConvertWorkspaces(inv.Context(), client, filter.Filter(), WorkspaceListRowFromWorkspace)
|
res, err := QueryConvertWorkspaces(inv.Context(), client, filter.Filter(), WorkspaceListRowFromWorkspace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
+5
-6
@@ -8,24 +8,23 @@ import (
|
|||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/coder/coder/v2/cli/cliui"
|
"github.com/coder/coder/v2/cli/cliui"
|
||||||
"github.com/coder/coder/v2/codersdk"
|
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) logout() *serpent.Command {
|
func (r *RootCmd) logout() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "logout",
|
Use: "logout",
|
||||||
Short: "Unauthenticate your local session",
|
Short: "Unauthenticate your local session",
|
||||||
Middleware: serpent.Chain(
|
|
||||||
r.InitClient(client),
|
|
||||||
),
|
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
var errors []error
|
var errors []error
|
||||||
|
|
||||||
config := r.createConfig()
|
config := r.createConfig()
|
||||||
|
|
||||||
var err error
|
|
||||||
_, err = cliui.Prompt(inv, cliui.PromptOptions{
|
_, err = cliui.Prompt(inv, cliui.PromptOptions{
|
||||||
Text: "Are you sure you want to log out?",
|
Text: "Are you sure you want to log out?",
|
||||||
IsConfirm: true,
|
IsConfirm: true,
|
||||||
|
|||||||
+5
-6
@@ -9,22 +9,21 @@ import (
|
|||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/coder/coder/v2/coderd/healthcheck/derphealth"
|
"github.com/coder/coder/v2/coderd/healthcheck/derphealth"
|
||||||
"github.com/coder/coder/v2/codersdk"
|
|
||||||
"github.com/coder/coder/v2/codersdk/healthsdk"
|
"github.com/coder/coder/v2/codersdk/healthsdk"
|
||||||
"github.com/coder/coder/v2/codersdk/workspacesdk"
|
"github.com/coder/coder/v2/codersdk/workspacesdk"
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) netcheck() *serpent.Command {
|
func (r *RootCmd) netcheck() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "netcheck",
|
Use: "netcheck",
|
||||||
Short: "Print network debug information for DERP and STUN",
|
Short: "Print network debug information for DERP and STUN",
|
||||||
Middleware: serpent.Chain(
|
|
||||||
r.InitClient(client),
|
|
||||||
),
|
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(inv.Context(), 30*time.Second)
|
ctx, cancel := context.WithTimeout(inv.Context(), 30*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
|
|||||||
+22
-11
@@ -47,16 +47,19 @@ func (r *RootCmd) notifications() *serpent.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) pauseNotifications() *serpent.Command {
|
func (r *RootCmd) pauseNotifications() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "pause",
|
Use: "pause",
|
||||||
Short: "Pause notifications",
|
Short: "Pause notifications",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
err := client.PutNotificationsSettings(inv.Context(), codersdk.NotificationsSettings{
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.PutNotificationsSettings(inv.Context(), codersdk.NotificationsSettings{
|
||||||
NotifierPaused: true,
|
NotifierPaused: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -71,16 +74,19 @@ func (r *RootCmd) pauseNotifications() *serpent.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) resumeNotifications() *serpent.Command {
|
func (r *RootCmd) resumeNotifications() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "resume",
|
Use: "resume",
|
||||||
Short: "Resume notifications",
|
Short: "Resume notifications",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
err := client.PutNotificationsSettings(inv.Context(), codersdk.NotificationsSettings{
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.PutNotificationsSettings(inv.Context(), codersdk.NotificationsSettings{
|
||||||
NotifierPaused: false,
|
NotifierPaused: false,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -95,15 +101,18 @@ func (r *RootCmd) resumeNotifications() *serpent.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) testNotifications() *serpent.Command {
|
func (r *RootCmd) testNotifications() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "test",
|
Use: "test",
|
||||||
Short: "Send a test notification",
|
Short: "Send a test notification",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err := client.PostTestNotification(inv.Context()); err != nil {
|
if err := client.PostTestNotification(inv.Context()); err != nil {
|
||||||
return xerrors.Errorf("unable to post test notification: %w", err)
|
return xerrors.Errorf("unable to post test notification: %w", err)
|
||||||
}
|
}
|
||||||
@@ -116,16 +125,18 @@ func (r *RootCmd) testNotifications() *serpent.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) customNotifications() *serpent.Command {
|
func (r *RootCmd) customNotifications() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "custom <title> <message>",
|
Use: "custom <title> <message>",
|
||||||
Short: "Send a custom notification",
|
Short: "Send a custom notification",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(2),
|
serpent.RequireNArgs(2),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
err := client.PostCustomNotification(inv.Context(), codersdk.CustomNotificationRequest{
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = client.PostCustomNotification(inv.Context(), codersdk.CustomNotificationRequest{
|
||||||
Content: &codersdk.CustomNotificationContent{
|
Content: &codersdk.CustomNotificationContent{
|
||||||
Title: inv.Args[0],
|
Title: inv.Args[0],
|
||||||
Message: inv.Args[1],
|
Message: inv.Args[1],
|
||||||
|
|||||||
+12
-10
@@ -41,24 +41,25 @@ const vscodeDesktopName = "VS Code Desktop"
|
|||||||
|
|
||||||
func (r *RootCmd) openVSCode() *serpent.Command {
|
func (r *RootCmd) openVSCode() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
generateToken bool
|
generateToken bool
|
||||||
testOpenError bool
|
testOpenError bool
|
||||||
appearanceConfig codersdk.AppearanceConfig
|
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "vscode <workspace> [<directory in workspace>]",
|
Use: "vscode <workspace> [<directory in workspace>]",
|
||||||
Short: fmt.Sprintf("Open a workspace in %s", vscodeDesktopName),
|
Short: fmt.Sprintf("Open a workspace in %s", vscodeDesktopName),
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireRangeArgs(1, 2),
|
serpent.RequireRangeArgs(1, 2),
|
||||||
r.InitClient(client),
|
|
||||||
initAppearance(client, &appearanceConfig),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
ctx, cancel := context.WithCancel(inv.Context())
|
ctx, cancel := context.WithCancel(inv.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
appearanceConfig := initAppearance(ctx, client)
|
||||||
|
|
||||||
// Check if we're inside a workspace, and especially inside _this_
|
// Check if we're inside a workspace, and especially inside _this_
|
||||||
// workspace so we can perform path resolution/expansion. Generally,
|
// workspace so we can perform path resolution/expansion. Generally,
|
||||||
@@ -299,15 +300,16 @@ func (r *RootCmd) openApp() *serpent.Command {
|
|||||||
testOpenError bool
|
testOpenError bool
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "app <workspace> <app slug>",
|
Use: "app <workspace> <app slug>",
|
||||||
Short: "Open a workspace application.",
|
Short: "Open a workspace application.",
|
||||||
Middleware: serpent.Chain(
|
|
||||||
r.InitClient(client),
|
|
||||||
),
|
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(inv.Context())
|
ctx, cancel := context.WithCancel(inv.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -37,7 +37,6 @@ func (r *RootCmd) organizations() *serpent.Command {
|
|||||||
func (r *RootCmd) showOrganization(orgContext *OrganizationContext) *serpent.Command {
|
func (r *RootCmd) showOrganization(orgContext *OrganizationContext) *serpent.Command {
|
||||||
var (
|
var (
|
||||||
stringFormat func(orgs []codersdk.Organization) (string, error)
|
stringFormat func(orgs []codersdk.Organization) (string, error)
|
||||||
client = new(codersdk.Client)
|
|
||||||
formatter = cliui.NewOutputFormatter(
|
formatter = cliui.NewOutputFormatter(
|
||||||
cliui.ChangeFormatterData(cliui.TextFormat(), func(data any) (any, error) {
|
cliui.ChangeFormatterData(cliui.TextFormat(), func(data any) (any, error) {
|
||||||
typed, ok := data.([]codersdk.Organization)
|
typed, ok := data.([]codersdk.Organization)
|
||||||
@@ -77,7 +76,6 @@ func (r *RootCmd) showOrganization(orgContext *OrganizationContext) *serpent.Com
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
r.InitClient(client),
|
|
||||||
serpent.RequireRangeArgs(0, 1),
|
serpent.RequireRangeArgs(0, 1),
|
||||||
),
|
),
|
||||||
Options: serpent.OptionSet{
|
Options: serpent.OptionSet{
|
||||||
@@ -90,13 +88,17 @@ func (r *RootCmd) showOrganization(orgContext *OrganizationContext) *serpent.Com
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
orgArg := "selected"
|
orgArg := "selected"
|
||||||
if len(inv.Args) >= 1 {
|
if len(inv.Args) >= 1 {
|
||||||
orgArg = inv.Args[0]
|
orgArg = inv.Args[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
var orgs []codersdk.Organization
|
var orgs []codersdk.Organization
|
||||||
var err error
|
|
||||||
switch strings.ToLower(orgArg) {
|
switch strings.ToLower(orgArg) {
|
||||||
case "selected":
|
case "selected":
|
||||||
stringFormat = func(orgs []codersdk.Organization) (string, error) {
|
stringFormat = func(orgs []codersdk.Organization) (string, error) {
|
||||||
|
|||||||
@@ -12,22 +12,24 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) createOrganization() *serpent.Command {
|
func (r *RootCmd) createOrganization() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "create <organization name>",
|
Use: "create <organization name>",
|
||||||
Short: "Create a new organization.",
|
Short: "Create a new organization.",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
r.InitClient(client),
|
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
),
|
),
|
||||||
Options: serpent.OptionSet{
|
Options: serpent.OptionSet{
|
||||||
cliui.SkipPromptOption(),
|
cliui.SkipPromptOption(),
|
||||||
},
|
},
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
orgName := inv.Args[0]
|
orgName := inv.Args[0]
|
||||||
|
|
||||||
err := codersdk.NameValid(orgName)
|
err = codersdk.NameValid(orgName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("organization name %q is invalid: %w", orgName, err)
|
return xerrors.Errorf("organization name %q is invalid: %w", orgName, err)
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-13
@@ -31,16 +31,17 @@ func (r *RootCmd) organizationMembers(orgContext *OrganizationContext) *serpent.
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) removeOrganizationMember(orgContext *OrganizationContext) *serpent.Command {
|
func (r *RootCmd) removeOrganizationMember(orgContext *OrganizationContext) *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "remove <username | user_id>",
|
Use: "remove <username | user_id>",
|
||||||
Short: "Remove a new member to the current organization",
|
Short: "Remove a new member to the current organization",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
r.InitClient(client),
|
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
organization, err := orgContext.Selected(inv, client)
|
organization, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -62,16 +63,17 @@ func (r *RootCmd) removeOrganizationMember(orgContext *OrganizationContext) *ser
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) addOrganizationMember(orgContext *OrganizationContext) *serpent.Command {
|
func (r *RootCmd) addOrganizationMember(orgContext *OrganizationContext) *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "add <username | user_id>",
|
Use: "add <username | user_id>",
|
||||||
Short: "Add a new member to the current organization",
|
Short: "Add a new member to the current organization",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
r.InitClient(client),
|
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
organization, err := orgContext.Selected(inv, client)
|
organization, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -93,16 +95,15 @@ func (r *RootCmd) addOrganizationMember(orgContext *OrganizationContext) *serpen
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) assignOrganizationRoles(orgContext *OrganizationContext) *serpent.Command {
|
func (r *RootCmd) assignOrganizationRoles(orgContext *OrganizationContext) *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "edit-roles <username | user_id> [roles...]",
|
Use: "edit-roles <username | user_id> [roles...]",
|
||||||
Aliases: []string{"edit-role"},
|
Aliases: []string{"edit-role"},
|
||||||
Short: "Edit organization member's roles",
|
Short: "Edit organization member's roles",
|
||||||
Middleware: serpent.Chain(
|
|
||||||
r.InitClient(client),
|
|
||||||
),
|
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
organization, err := orgContext.Selected(inv, client)
|
organization, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -141,15 +142,18 @@ func (r *RootCmd) listOrganizationMembers(orgContext *OrganizationContext) *serp
|
|||||||
cliui.JSONFormat(),
|
cliui.JSONFormat(),
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Short: "List all organization members",
|
Short: "List all organization members",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
organization, err := orgContext.Selected(inv, client)
|
organization, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -54,14 +54,15 @@ func (r *RootCmd) showOrganizationRoles(orgContext *OrganizationContext) *serpen
|
|||||||
cliui.JSONFormat(),
|
cliui.JSONFormat(),
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "show [role_names ...]",
|
Use: "show [role_names ...]",
|
||||||
Short: "Show role(s)",
|
Short: "Show role(s)",
|
||||||
Middleware: serpent.Chain(
|
|
||||||
r.InitClient(client),
|
|
||||||
),
|
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
org, err := orgContext.Selected(inv, client)
|
org, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -117,7 +118,6 @@ func (r *RootCmd) createOrganizationRole(orgContext *OrganizationContext) *serpe
|
|||||||
jsonInput bool
|
jsonInput bool
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "create <role_name>",
|
Use: "create <role_name>",
|
||||||
Short: "Create a new organization custom role",
|
Short: "Create a new organization custom role",
|
||||||
@@ -144,10 +144,13 @@ func (r *RootCmd) createOrganizationRole(orgContext *OrganizationContext) *serpe
|
|||||||
},
|
},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireRangeArgs(0, 1),
|
serpent.RequireRangeArgs(0, 1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
org, err := orgContext.Selected(inv, client)
|
org, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -240,7 +243,6 @@ func (r *RootCmd) updateOrganizationRole(orgContext *OrganizationContext) *serpe
|
|||||||
jsonInput bool
|
jsonInput bool
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "update <role_name>",
|
Use: "update <role_name>",
|
||||||
Short: "Update an organization custom role",
|
Short: "Update an organization custom role",
|
||||||
@@ -267,9 +269,13 @@ func (r *RootCmd) updateOrganizationRole(orgContext *OrganizationContext) *serpe
|
|||||||
},
|
},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireRangeArgs(0, 1),
|
serpent.RequireRangeArgs(0, 1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
org, err := orgContext.Selected(inv, client)
|
org, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -95,7 +95,6 @@ type organizationSetting struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) setOrganizationSettings(orgContext *OrganizationContext, settings []organizationSetting) *serpent.Command {
|
func (r *RootCmd) setOrganizationSettings(orgContext *OrganizationContext, settings []organizationSetting) *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "set",
|
Use: "set",
|
||||||
Short: "Update specified organization setting.",
|
Short: "Update specified organization setting.",
|
||||||
@@ -108,7 +107,6 @@ func (r *RootCmd) setOrganizationSettings(orgContext *OrganizationContext, setti
|
|||||||
Options: []serpent.Option{},
|
Options: []serpent.Option{},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return inv.Command.HelpHandler(inv)
|
return inv.Command.HelpHandler(inv)
|
||||||
@@ -124,12 +122,15 @@ func (r *RootCmd) setOrganizationSettings(orgContext *OrganizationContext, setti
|
|||||||
Options: []serpent.Option{},
|
Options: []serpent.Option{},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
var org codersdk.Organization
|
var org codersdk.Organization
|
||||||
var err error
|
|
||||||
|
|
||||||
if !set.DisableOrgContext {
|
if !set.DisableOrgContext {
|
||||||
org, err = orgContext.Selected(inv, client)
|
org, err = orgContext.Selected(inv, client)
|
||||||
@@ -170,7 +171,6 @@ func (r *RootCmd) setOrganizationSettings(orgContext *OrganizationContext, setti
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) printOrganizationSetting(orgContext *OrganizationContext, settings []organizationSetting) *serpent.Command {
|
func (r *RootCmd) printOrganizationSetting(orgContext *OrganizationContext, settings []organizationSetting) *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "show",
|
Use: "show",
|
||||||
Short: "Outputs specified organization setting.",
|
Short: "Outputs specified organization setting.",
|
||||||
@@ -183,7 +183,6 @@ func (r *RootCmd) printOrganizationSetting(orgContext *OrganizationContext, sett
|
|||||||
Options: []serpent.Option{},
|
Options: []serpent.Option{},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
return inv.Command.HelpHandler(inv)
|
return inv.Command.HelpHandler(inv)
|
||||||
@@ -199,13 +198,15 @@ func (r *RootCmd) printOrganizationSetting(orgContext *OrganizationContext, sett
|
|||||||
Options: []serpent.Option{},
|
Options: []serpent.Option{},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
var org codersdk.Organization
|
var org codersdk.Organization
|
||||||
var err error
|
|
||||||
|
|
||||||
if !set.DisableOrgContext {
|
if !set.DisableOrgContext {
|
||||||
org, err = orgContext.Selected(inv, client)
|
org, err = orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+10
-10
@@ -84,28 +84,28 @@ func (s *pingSummary) Write(w io.Writer) {
|
|||||||
|
|
||||||
func (r *RootCmd) ping() *serpent.Command {
|
func (r *RootCmd) ping() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
pingNum int64
|
pingNum int64
|
||||||
pingTimeout time.Duration
|
pingTimeout time.Duration
|
||||||
pingWait time.Duration
|
pingWait time.Duration
|
||||||
pingTimeLocal bool
|
pingTimeLocal bool
|
||||||
pingTimeUTC bool
|
pingTimeUTC bool
|
||||||
appearanceConfig codersdk.AppearanceConfig
|
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "ping <workspace>",
|
Use: "ping <workspace>",
|
||||||
Short: "Ping a workspace",
|
Short: "Ping a workspace",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
initAppearance(client, &appearanceConfig),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
ctx, cancel := context.WithCancel(inv.Context())
|
ctx, cancel := context.WithCancel(inv.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
appearanceConfig := initAppearance(ctx, client)
|
||||||
notifyCtx, notifyCancel := inv.SignalNotifyContext(ctx, StopSignals...)
|
notifyCtx, notifyCancel := inv.SignalNotifyContext(ctx, StopSignals...)
|
||||||
defer notifyCancel()
|
defer notifyCancel()
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -38,9 +38,7 @@ func (r *RootCmd) portForward() *serpent.Command {
|
|||||||
tcpForwards []string // <port>:<port>
|
tcpForwards []string // <port>:<port>
|
||||||
udpForwards []string // <port>:<port>
|
udpForwards []string // <port>:<port>
|
||||||
disableAutostart bool
|
disableAutostart bool
|
||||||
appearanceConfig codersdk.AppearanceConfig
|
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "port-forward <workspace>",
|
Use: "port-forward <workspace>",
|
||||||
Short: `Forward ports from a workspace to the local machine. For reverse port forwarding, use "coder ssh -R".`,
|
Short: `Forward ports from a workspace to the local machine. For reverse port forwarding, use "coder ssh -R".`,
|
||||||
@@ -69,12 +67,15 @@ func (r *RootCmd) portForward() *serpent.Command {
|
|||||||
),
|
),
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
initAppearance(client, &appearanceConfig),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
ctx, cancel := context.WithCancel(inv.Context())
|
ctx, cancel := context.WithCancel(inv.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
appearanceConfig := initAppearance(ctx, client)
|
||||||
|
|
||||||
specs, err := parsePortForwards(tcpForwards, udpForwards)
|
specs, err := parsePortForwards(tcpForwards, udpForwards)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ func (r *RootCmd) provisionerJobsList() *serpent.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
client = new(codersdk.Client)
|
|
||||||
orgContext = NewOrganizationContext()
|
orgContext = NewOrganizationContext()
|
||||||
formatter = cliui.NewOutputFormatter(
|
formatter = cliui.NewOutputFormatter(
|
||||||
cliui.TableFormat([]provisionerJobRow{}, []string{"created at", "id", "type", "template display name", "status", "queue", "tags"}),
|
cliui.TableFormat([]provisionerJobRow{}, []string{"created at", "id", "type", "template display name", "status", "queue", "tags"}),
|
||||||
@@ -54,10 +53,13 @@ func (r *RootCmd) provisionerJobsList() *serpent.Command {
|
|||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
org, err := orgContext.Selected(inv, client)
|
org, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("current organization: %w", err)
|
return xerrors.Errorf("current organization: %w", err)
|
||||||
@@ -129,19 +131,19 @@ func (r *RootCmd) provisionerJobsList() *serpent.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) provisionerJobsCancel() *serpent.Command {
|
func (r *RootCmd) provisionerJobsCancel() *serpent.Command {
|
||||||
var (
|
orgContext := NewOrganizationContext()
|
||||||
client = new(codersdk.Client)
|
|
||||||
orgContext = NewOrganizationContext()
|
|
||||||
)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "cancel <job_id>",
|
Use: "cancel <job_id>",
|
||||||
Short: "Cancel a provisioner job",
|
Short: "Cancel a provisioner job",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
org, err := orgContext.Selected(inv, client)
|
org, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("current organization: %w", err)
|
return xerrors.Errorf("current organization: %w", err)
|
||||||
|
|||||||
+4
-3
@@ -35,7 +35,6 @@ func (r *RootCmd) provisionerList() *serpent.Command {
|
|||||||
OrganizationName string `json:"organization_name" table:"organization"`
|
OrganizationName string `json:"organization_name" table:"organization"`
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
client = new(codersdk.Client)
|
|
||||||
orgContext = NewOrganizationContext()
|
orgContext = NewOrganizationContext()
|
||||||
formatter = cliui.NewOutputFormatter(
|
formatter = cliui.NewOutputFormatter(
|
||||||
cliui.TableFormat([]provisionerDaemonRow{}, []string{"created at", "last seen at", "key name", "name", "version", "status", "tags"}),
|
cliui.TableFormat([]provisionerDaemonRow{}, []string{"created at", "last seen at", "key name", "name", "version", "status", "tags"}),
|
||||||
@@ -53,11 +52,13 @@ func (r *RootCmd) provisionerList() *serpent.Command {
|
|||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
org, err := orgContext.Selected(inv, client)
|
org, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("current organization: %w", err)
|
return xerrors.Errorf("current organization: %w", err)
|
||||||
|
|||||||
+7
-5
@@ -14,13 +14,15 @@ import (
|
|||||||
|
|
||||||
func (r *RootCmd) publickey() *serpent.Command {
|
func (r *RootCmd) publickey() *serpent.Command {
|
||||||
var reset bool
|
var reset bool
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "publickey",
|
Use: "publickey",
|
||||||
Aliases: []string{"pubkey"},
|
Aliases: []string{"pubkey"},
|
||||||
Short: "Output your Coder public key used for Git operations",
|
Short: "Output your Coder public key used for Git operations",
|
||||||
Middleware: r.InitClient(client),
|
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if reset {
|
if reset {
|
||||||
// Confirm prompt if using --reset. We don't want to accidentally
|
// Confirm prompt if using --reset. We don't want to accidentally
|
||||||
// reset our public key.
|
// reset our public key.
|
||||||
|
|||||||
+6
-4
@@ -13,18 +13,20 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) rename() *serpent.Command {
|
func (r *RootCmd) rename() *serpent.Command {
|
||||||
var appearanceConfig codersdk.AppearanceConfig
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "rename <workspace> <new name>",
|
Use: "rename <workspace> <new name>",
|
||||||
Short: "Rename a workspace",
|
Short: "Rename a workspace",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(2),
|
serpent.RequireNArgs(2),
|
||||||
r.InitClient(client),
|
|
||||||
initAppearance(client, &appearanceConfig),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
appearanceConfig := initAppearance(inv.Context(), client)
|
||||||
|
|
||||||
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("get workspace: %w", err)
|
return xerrors.Errorf("get workspace: %w", err)
|
||||||
|
|||||||
+5
-2
@@ -19,17 +19,20 @@ func (r *RootCmd) restart() *serpent.Command {
|
|||||||
bflags buildFlags
|
bflags buildFlags
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "restart <workspace>",
|
Use: "restart <workspace>",
|
||||||
Short: "Restart a workspace",
|
Short: "Restart a workspace",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Options: serpent.OptionSet{cliui.SkipPromptOption()},
|
Options: serpent.OptionSet{cliui.SkipPromptOption()},
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
out := inv.Stdout
|
out := inv.Stdout
|
||||||
|
|
||||||
|
|||||||
+92
-100
@@ -494,110 +494,106 @@ type RootCmd struct {
|
|||||||
noFeatureWarning bool
|
noFeatureWarning bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitClient authenticates the client with files from disk
|
// InitClient creates and configures a new client with authentication, telemetry,
|
||||||
// and injects header middlewares for telemetry, authentication,
|
|
||||||
// and version checks.
|
// and version checks.
|
||||||
func (r *RootCmd) InitClient(client *codersdk.Client) serpent.MiddlewareFunc {
|
func (r *RootCmd) InitClient(inv *serpent.Invocation) (*codersdk.Client, error) {
|
||||||
return func(next serpent.HandlerFunc) serpent.HandlerFunc {
|
conf := r.createConfig()
|
||||||
return func(inv *serpent.Invocation) error {
|
var err error
|
||||||
conf := r.createConfig()
|
// Read the client URL stored on disk.
|
||||||
var err error
|
if r.clientURL == nil || r.clientURL.String() == "" {
|
||||||
// Read the client URL stored on disk.
|
rawURL, err := conf.URL().Read()
|
||||||
if r.clientURL == nil || r.clientURL.String() == "" {
|
// If the configuration files are absent, the user is logged out
|
||||||
rawURL, err := conf.URL().Read()
|
if os.IsNotExist(err) {
|
||||||
// If the configuration files are absent, the user is logged out
|
binPath, err := os.Executable()
|
||||||
if os.IsNotExist(err) {
|
|
||||||
binPath, err := os.Executable()
|
|
||||||
if err != nil {
|
|
||||||
binPath = "coder"
|
|
||||||
}
|
|
||||||
return xerrors.Errorf(notLoggedInMessage, binPath)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
r.clientURL, err = url.Parse(strings.TrimSpace(rawURL))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Read the token stored on disk.
|
|
||||||
if r.token == "" {
|
|
||||||
r.token, err = conf.Session().Read()
|
|
||||||
// Even if there isn't a token, we don't care.
|
|
||||||
// Some API routes can be unauthenticated.
|
|
||||||
if err != nil && !os.IsNotExist(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = r.configureClient(inv.Context(), client, r.clientURL, inv)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
binPath = "coder"
|
||||||
}
|
}
|
||||||
client.SetSessionToken(r.token)
|
return nil, xerrors.Errorf(notLoggedInMessage, binPath)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if r.debugHTTP {
|
r.clientURL, err = url.Parse(strings.TrimSpace(rawURL))
|
||||||
client.PlainLogger = os.Stderr
|
if err != nil {
|
||||||
client.SetLogBodies(true)
|
return nil, err
|
||||||
}
|
|
||||||
client.DisableDirectConnections = r.disableDirect
|
|
||||||
return next(inv)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Read the token stored on disk.
|
||||||
|
if r.token == "" {
|
||||||
|
r.token, err = conf.Session().Read()
|
||||||
|
// Even if there isn't a token, we don't care.
|
||||||
|
// Some API routes can be unauthenticated.
|
||||||
|
if err != nil && !os.IsNotExist(err) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &codersdk.Client{}
|
||||||
|
err = r.configureClient(inv.Context(), client, r.clientURL, inv)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
client.SetSessionToken(r.token)
|
||||||
|
|
||||||
|
if r.debugHTTP {
|
||||||
|
client.PlainLogger = os.Stderr
|
||||||
|
client.SetLogBodies(true)
|
||||||
|
}
|
||||||
|
client.DisableDirectConnections = r.disableDirect
|
||||||
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TryInitClient is similar to InitClient but doesn't error when credentials are missing.
|
// TryInitClient is similar to InitClient but doesn't error when credentials are missing.
|
||||||
// This allows commands to run without requiring authentication, but still use auth if available.
|
// This allows commands to run without requiring authentication, but still use auth if available.
|
||||||
func (r *RootCmd) TryInitClient(client *codersdk.Client) serpent.MiddlewareFunc {
|
func (r *RootCmd) TryInitClient(inv *serpent.Invocation) (*codersdk.Client, error) {
|
||||||
return func(next serpent.HandlerFunc) serpent.HandlerFunc {
|
conf := r.createConfig()
|
||||||
return func(inv *serpent.Invocation) error {
|
var err error
|
||||||
conf := r.createConfig()
|
// Read the client URL stored on disk.
|
||||||
var err error
|
if r.clientURL == nil || r.clientURL.String() == "" {
|
||||||
// Read the client URL stored on disk.
|
rawURL, err := conf.URL().Read()
|
||||||
if r.clientURL == nil || r.clientURL.String() == "" {
|
// If the configuration files are absent, just continue without URL
|
||||||
rawURL, err := conf.URL().Read()
|
if err != nil {
|
||||||
// If the configuration files are absent, just continue without URL
|
// Continue with a nil or empty URL
|
||||||
if err != nil {
|
if !os.IsNotExist(err) {
|
||||||
// Continue with a nil or empty URL
|
return nil, err
|
||||||
if !os.IsNotExist(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
r.clientURL, err = url.Parse(strings.TrimSpace(rawURL))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Read the token stored on disk.
|
} else {
|
||||||
if r.token == "" {
|
r.clientURL, err = url.Parse(strings.TrimSpace(rawURL))
|
||||||
r.token, err = conf.Session().Read()
|
if err != nil {
|
||||||
// Even if there isn't a token, we don't care.
|
return nil, err
|
||||||
// Some API routes can be unauthenticated.
|
|
||||||
if err != nil && !os.IsNotExist(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only configure the client if we have a URL
|
|
||||||
if r.clientURL != nil && r.clientURL.String() != "" {
|
|
||||||
err = r.configureClient(inv.Context(), client, r.clientURL, inv)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
client.SetSessionToken(r.token)
|
|
||||||
|
|
||||||
if r.debugHTTP {
|
|
||||||
client.PlainLogger = os.Stderr
|
|
||||||
client.SetLogBodies(true)
|
|
||||||
}
|
|
||||||
client.DisableDirectConnections = r.disableDirect
|
|
||||||
}
|
|
||||||
return next(inv)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Read the token stored on disk.
|
||||||
|
if r.token == "" {
|
||||||
|
r.token, err = conf.Session().Read()
|
||||||
|
// Even if there isn't a token, we don't care.
|
||||||
|
// Some API routes can be unauthenticated.
|
||||||
|
if err != nil && !os.IsNotExist(err) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only configure the client if we have a URL
|
||||||
|
if r.clientURL != nil && r.clientURL.String() != "" {
|
||||||
|
client := &codersdk.Client{}
|
||||||
|
err = r.configureClient(inv.Context(), client, r.clientURL, inv)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
client.SetSessionToken(r.token)
|
||||||
|
|
||||||
|
if r.debugHTTP {
|
||||||
|
client.PlainLogger = os.Stderr
|
||||||
|
client.SetLogBodies(true)
|
||||||
|
}
|
||||||
|
client.DisableDirectConnections = r.disableDirect
|
||||||
|
return client, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a minimal client if no URL is available
|
||||||
|
return &codersdk.Client{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// HeaderTransport creates a new transport that executes `--header-command`
|
// HeaderTransport creates a new transport that executes `--header-command`
|
||||||
@@ -817,17 +813,13 @@ func namedWorkspace(ctx context.Context, client *codersdk.Client, identifier str
|
|||||||
return client.WorkspaceByOwnerAndName(ctx, owner, name, codersdk.WorkspaceOptions{})
|
return client.WorkspaceByOwnerAndName(ctx, owner, name, codersdk.WorkspaceOptions{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func initAppearance(client *codersdk.Client, outConfig *codersdk.AppearanceConfig) serpent.MiddlewareFunc {
|
func initAppearance(ctx context.Context, client *codersdk.Client) codersdk.AppearanceConfig {
|
||||||
return func(next serpent.HandlerFunc) serpent.HandlerFunc {
|
// best effort
|
||||||
return func(inv *serpent.Invocation) error {
|
cfg, _ := client.Appearance(ctx)
|
||||||
cfg, _ := client.Appearance(inv.Context())
|
if cfg.DocsURL == "" {
|
||||||
if cfg.DocsURL == "" {
|
cfg.DocsURL = codersdk.DefaultDocsURL()
|
||||||
cfg.DocsURL = codersdk.DefaultDocsURL()
|
|
||||||
}
|
|
||||||
*outConfig = cfg
|
|
||||||
return next(inv)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
// createConfig consumes the global configuration flag to produce a config root.
|
// createConfig consumes the global configuration flag to produce a config root.
|
||||||
|
|||||||
+16
-8
@@ -90,16 +90,18 @@ func (r *RootCmd) scheduleShow() *serpent.Command {
|
|||||||
cliui.JSONFormat(),
|
cliui.JSONFormat(),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
showCmd := &serpent.Command{
|
showCmd := &serpent.Command{
|
||||||
Use: "show <workspace | --search <query> | --all>",
|
Use: "show <workspace | --search <query> | --all>",
|
||||||
Short: "Show workspace schedules",
|
Short: "Show workspace schedules",
|
||||||
Long: scheduleShowDescriptionLong,
|
Long: scheduleShowDescriptionLong,
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireRangeArgs(0, 1),
|
serpent.RequireRangeArgs(0, 1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
// To preserve existing behavior, if an argument is passed we will
|
// To preserve existing behavior, if an argument is passed we will
|
||||||
// only show the schedule for that workspace.
|
// only show the schedule for that workspace.
|
||||||
// This will clobber the search query if one is passed.
|
// This will clobber the search query if one is passed.
|
||||||
@@ -137,7 +139,6 @@ func (r *RootCmd) scheduleShow() *serpent.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) scheduleStart() *serpent.Command {
|
func (r *RootCmd) scheduleStart() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "start <workspace-name> { <start-time> [day-of-week] [location] | manual }",
|
Use: "start <workspace-name> { <start-time> [day-of-week] [location] | manual }",
|
||||||
Long: scheduleStartDescriptionLong + "\n" + FormatExamples(
|
Long: scheduleStartDescriptionLong + "\n" + FormatExamples(
|
||||||
@@ -149,9 +150,12 @@ func (r *RootCmd) scheduleStart() *serpent.Command {
|
|||||||
Short: "Edit workspace start schedule",
|
Short: "Edit workspace start schedule",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireRangeArgs(2, 4),
|
serpent.RequireRangeArgs(2, 4),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -193,7 +197,6 @@ func (r *RootCmd) scheduleStart() *serpent.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) scheduleStop() *serpent.Command {
|
func (r *RootCmd) scheduleStop() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
return &serpent.Command{
|
return &serpent.Command{
|
||||||
Use: "stop <workspace-name> { <duration> | manual }",
|
Use: "stop <workspace-name> { <duration> | manual }",
|
||||||
Long: scheduleStopDescriptionLong + "\n" + FormatExamples(
|
Long: scheduleStopDescriptionLong + "\n" + FormatExamples(
|
||||||
@@ -204,9 +207,12 @@ func (r *RootCmd) scheduleStop() *serpent.Command {
|
|||||||
Short: "Edit workspace stop schedule",
|
Short: "Edit workspace stop schedule",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(2),
|
serpent.RequireNArgs(2),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -244,7 +250,6 @@ func (r *RootCmd) scheduleStop() *serpent.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) scheduleExtend() *serpent.Command {
|
func (r *RootCmd) scheduleExtend() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
extendCmd := &serpent.Command{
|
extendCmd := &serpent.Command{
|
||||||
Use: "extend <workspace-name> <duration from now>",
|
Use: "extend <workspace-name> <duration from now>",
|
||||||
Aliases: []string{"override-stop"},
|
Aliases: []string{"override-stop"},
|
||||||
@@ -256,9 +261,12 @@ func (r *RootCmd) scheduleExtend() *serpent.Command {
|
|||||||
),
|
),
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(2),
|
serpent.RequireNArgs(2),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
extendDuration, err := parseDuration(inv.Args[1])
|
extendDuration, err := parseDuration(inv.Args[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
+14
-7
@@ -36,17 +36,19 @@ func (r *RootCmd) sharing() *serpent.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) statusWorkspaceSharing() *serpent.Command {
|
func (r *RootCmd) statusWorkspaceSharing() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "status <workspace>",
|
Use: "status <workspace>",
|
||||||
Short: "List all users and groups the given Workspace is shared with.",
|
Short: "List all users and groups the given Workspace is shared with.",
|
||||||
Aliases: []string{"list"},
|
Aliases: []string{"list"},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
r.InitClient(client),
|
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("unable to fetch Workspace %s: %w", inv.Args[0], err)
|
return xerrors.Errorf("unable to fetch Workspace %s: %w", inv.Args[0], err)
|
||||||
@@ -72,7 +74,6 @@ func (r *RootCmd) statusWorkspaceSharing() *serpent.Command {
|
|||||||
|
|
||||||
func (r *RootCmd) shareWorkspace() *serpent.Command {
|
func (r *RootCmd) shareWorkspace() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
client = new(codersdk.Client)
|
|
||||||
users []string
|
users []string
|
||||||
groups []string
|
groups []string
|
||||||
|
|
||||||
@@ -98,10 +99,14 @@ func (r *RootCmd) shareWorkspace() *serpent.Command {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
r.InitClient(client),
|
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if len(users) == 0 && len(groups) == 0 {
|
if len(users) == 0 && len(groups) == 0 {
|
||||||
return xerrors.New("at least one user or group must be provided")
|
return xerrors.New("at least one user or group must be provided")
|
||||||
}
|
}
|
||||||
@@ -171,7 +176,6 @@ func (r *RootCmd) shareWorkspace() *serpent.Command {
|
|||||||
|
|
||||||
func (r *RootCmd) unshareWorkspace() *serpent.Command {
|
func (r *RootCmd) unshareWorkspace() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
client = new(codersdk.Client)
|
|
||||||
users []string
|
users []string
|
||||||
groups []string
|
groups []string
|
||||||
)
|
)
|
||||||
@@ -194,13 +198,16 @@ func (r *RootCmd) unshareWorkspace() *serpent.Command {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
r.InitClient(client),
|
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
if len(users) == 0 && len(groups) == 0 {
|
if len(users) == 0 && len(groups) == 0 {
|
||||||
return xerrors.New("at least one user or group must be provided")
|
return xerrors.New("at least one user or group must be provided")
|
||||||
}
|
}
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+5
-2
@@ -15,7 +15,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) show() *serpent.Command {
|
func (r *RootCmd) show() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
var details bool
|
var details bool
|
||||||
return &serpent.Command{
|
return &serpent.Command{
|
||||||
Use: "show <workspace>",
|
Use: "show <workspace>",
|
||||||
@@ -30,9 +29,13 @@ func (r *RootCmd) show() *serpent.Command {
|
|||||||
},
|
},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
buildInfo, err := client.BuildInfo(inv.Context())
|
buildInfo, err := client.BuildInfo(inv.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("get server version: %w", err)
|
return xerrors.Errorf("get server version: %w", err)
|
||||||
|
|||||||
+10
-10
@@ -13,7 +13,6 @@ import (
|
|||||||
"cdr.dev/slog"
|
"cdr.dev/slog"
|
||||||
"cdr.dev/slog/sloggers/sloghuman"
|
"cdr.dev/slog/sloggers/sloghuman"
|
||||||
"github.com/coder/coder/v2/cli/cliui"
|
"github.com/coder/coder/v2/cli/cliui"
|
||||||
"github.com/coder/coder/v2/codersdk"
|
|
||||||
"github.com/coder/coder/v2/codersdk/workspacesdk"
|
"github.com/coder/coder/v2/codersdk/workspacesdk"
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
@@ -36,12 +35,11 @@ type speedtestTableItem struct {
|
|||||||
|
|
||||||
func (r *RootCmd) speedtest() *serpent.Command {
|
func (r *RootCmd) speedtest() *serpent.Command {
|
||||||
var (
|
var (
|
||||||
direct bool
|
direct bool
|
||||||
duration time.Duration
|
duration time.Duration
|
||||||
direction string
|
direction string
|
||||||
pcapFile string
|
pcapFile string
|
||||||
appearanceConfig codersdk.AppearanceConfig
|
formatter = cliui.NewOutputFormatter(
|
||||||
formatter = cliui.NewOutputFormatter(
|
|
||||||
cliui.ChangeFormatterData(cliui.TableFormat([]speedtestTableItem{}, []string{"Interval", "Throughput"}), func(data any) (any, error) {
|
cliui.ChangeFormatterData(cliui.TableFormat([]speedtestTableItem{}, []string{"Interval", "Throughput"}), func(data any) (any, error) {
|
||||||
res, ok := data.(SpeedtestResult)
|
res, ok := data.(SpeedtestResult)
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -65,19 +63,21 @@ func (r *RootCmd) speedtest() *serpent.Command {
|
|||||||
cliui.JSONFormat(),
|
cliui.JSONFormat(),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "speedtest <workspace>",
|
Use: "speedtest <workspace>",
|
||||||
Short: "Run upload and download tests from your machine to a workspace",
|
Short: "Run upload and download tests from your machine to a workspace",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
initAppearance(client, &appearanceConfig),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
ctx, cancel := context.WithCancel(inv.Context())
|
ctx, cancel := context.WithCancel(inv.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
appearanceConfig := initAppearance(ctx, client)
|
||||||
|
|
||||||
if direct && r.disableDirect {
|
if direct && r.disableDirect {
|
||||||
return xerrors.Errorf("--direct (-d) is incompatible with --%s", varDisableDirect)
|
return xerrors.Errorf("--direct (-d) is incompatible with --%s", varDisableDirect)
|
||||||
|
|||||||
+7
-5
@@ -79,15 +79,12 @@ func (r *RootCmd) ssh() *serpent.Command {
|
|||||||
env []string
|
env []string
|
||||||
usageApp string
|
usageApp string
|
||||||
disableAutostart bool
|
disableAutostart bool
|
||||||
appearanceConfig codersdk.AppearanceConfig
|
|
||||||
networkInfoDir string
|
networkInfoDir string
|
||||||
networkInfoInterval time.Duration
|
networkInfoInterval time.Duration
|
||||||
|
|
||||||
containerName string
|
containerName string
|
||||||
containerUser string
|
containerUser string
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
wsClient := workspacesdk.New(client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "ssh <workspace> [command]",
|
Use: "ssh <workspace> [command]",
|
||||||
@@ -111,10 +108,15 @@ func (r *RootCmd) ssh() *serpent.Command {
|
|||||||
return next(i)
|
return next(i)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
r.InitClient(client),
|
|
||||||
initAppearance(client, &appearanceConfig),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) (retErr error) {
|
Handler: func(inv *serpent.Invocation) (retErr error) {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
appearanceConfig := initAppearance(inv.Context(), client)
|
||||||
|
wsClient := workspacesdk.New(client)
|
||||||
|
|
||||||
command := strings.Join(inv.Args[1:], " ")
|
command := strings.Join(inv.Args[1:], " ")
|
||||||
|
|
||||||
// Before dialing the SSH server over TCP, capture Interrupt signals
|
// Before dialing the SSH server over TCP, capture Interrupt signals
|
||||||
|
|||||||
+5
-2
@@ -21,14 +21,12 @@ func (r *RootCmd) start() *serpent.Command {
|
|||||||
noWait bool
|
noWait bool
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "start <workspace>",
|
Use: "start <workspace>",
|
||||||
Short: "Start a workspace",
|
Short: "Start a workspace",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Options: serpent.OptionSet{
|
Options: serpent.OptionSet{
|
||||||
{
|
{
|
||||||
@@ -40,6 +38,11 @@ func (r *RootCmd) start() *serpent.Command {
|
|||||||
cliui.SkipPromptOption(),
|
cliui.SkipPromptOption(),
|
||||||
},
|
},
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
+8
-5
@@ -28,16 +28,17 @@ func (r *RootCmd) state() *serpent.Command {
|
|||||||
|
|
||||||
func (r *RootCmd) statePull() *serpent.Command {
|
func (r *RootCmd) statePull() *serpent.Command {
|
||||||
var buildNumber int64
|
var buildNumber int64
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "pull <workspace> [file]",
|
Use: "pull <workspace> [file]",
|
||||||
Short: "Pull a Terraform state file from a workspace.",
|
Short: "Pull a Terraform state file from a workspace.",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireRangeArgs(1, 2),
|
serpent.RequireRangeArgs(1, 2),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
var err error
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
var build codersdk.WorkspaceBuild
|
var build codersdk.WorkspaceBuild
|
||||||
if buildNumber == 0 {
|
if buildNumber == 0 {
|
||||||
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
||||||
@@ -86,15 +87,17 @@ func buildNumberOption(n *int64) serpent.Option {
|
|||||||
|
|
||||||
func (r *RootCmd) statePush() *serpent.Command {
|
func (r *RootCmd) statePush() *serpent.Command {
|
||||||
var buildNumber int64
|
var buildNumber int64
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "push <workspace> <file>",
|
Use: "push <workspace> <file>",
|
||||||
Short: "Push a Terraform state file to a workspace.",
|
Short: "Push a Terraform state file to a workspace.",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(2),
|
serpent.RequireNArgs(2),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
+6
-3
@@ -12,20 +12,23 @@ import (
|
|||||||
|
|
||||||
func (r *RootCmd) stop() *serpent.Command {
|
func (r *RootCmd) stop() *serpent.Command {
|
||||||
var bflags buildFlags
|
var bflags buildFlags
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "stop <workspace>",
|
Use: "stop <workspace>",
|
||||||
Short: "Stop a workspace",
|
Short: "Stop a workspace",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Options: serpent.OptionSet{
|
Options: serpent.OptionSet{
|
||||||
cliui.SkipPromptOption(),
|
cliui.SkipPromptOption(),
|
||||||
},
|
},
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
_, err := cliui.Prompt(inv, cliui.PromptOptions{
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = cliui.Prompt(inv, cliui.PromptOptions{
|
||||||
Text: "Confirm stop workspace?",
|
Text: "Confirm stop workspace?",
|
||||||
IsConfirm: true,
|
IsConfirm: true,
|
||||||
})
|
})
|
||||||
|
|||||||
+4
-2
@@ -62,16 +62,18 @@ var supportBundleBlurb = cliui.Bold("This will collect the following information
|
|||||||
func (r *RootCmd) supportBundle() *serpent.Command {
|
func (r *RootCmd) supportBundle() *serpent.Command {
|
||||||
var outputPath string
|
var outputPath string
|
||||||
var coderURLOverride string
|
var coderURLOverride string
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "bundle <workspace> [<agent>]",
|
Use: "bundle <workspace> [<agent>]",
|
||||||
Short: "Generate a support bundle to troubleshoot issues connecting to a workspace.",
|
Short: "Generate a support bundle to troubleshoot issues connecting to a workspace.",
|
||||||
Long: `This command generates a file containing detailed troubleshooting information about the Coder deployment and workspace connections. You must specify a single workspace (and optionally an agent name).`,
|
Long: `This command generates a file containing detailed troubleshooting information about the Coder deployment and workspace connections. You must specify a single workspace (and optionally an agent name).`,
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireRangeArgs(0, 2),
|
serpent.RequireRangeArgs(0, 2),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
var cliLogBuf bytes.Buffer
|
var cliLogBuf bytes.Buffer
|
||||||
cliLogW := sloghuman.Sink(&cliLogBuf)
|
cliLogW := sloghuman.Sink(&cliLogBuf)
|
||||||
cliLog := slog.Make(cliLogW).Leveled(slog.LevelDebug)
|
cliLog := slog.Make(cliLogW).Leveled(slog.LevelDebug)
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ func (r *RootCmd) templateCreate() *serpent.Command {
|
|||||||
uploadFlags templateUploadFlags
|
uploadFlags templateUploadFlags
|
||||||
orgContext = NewOrganizationContext()
|
orgContext = NewOrganizationContext()
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "create [name]",
|
Use: "create [name]",
|
||||||
Short: "DEPRECATED: Create a template from the current directory or as specified by flag",
|
Short: "DEPRECATED: Create a template from the current directory or as specified by flag",
|
||||||
@@ -43,9 +42,12 @@ func (r *RootCmd) templateCreate() *serpent.Command {
|
|||||||
"Use `coder templates push` command for creating and updating templates. \n"+
|
"Use `coder templates push` command for creating and updating templates. \n"+
|
||||||
"Use `coder templates edit` command for editing template settings. ",
|
"Use `coder templates edit` command for editing template settings. ",
|
||||||
),
|
),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
isTemplateSchedulingOptionsSet := failureTTL != 0 || dormancyThreshold != 0 || dormancyAutoDeletion != 0
|
isTemplateSchedulingOptionsSet := failureTTL != 0 || dormancyThreshold != 0 || dormancyAutoDeletion != 0
|
||||||
|
|
||||||
if isTemplateSchedulingOptionsSet || requireActiveVersion {
|
if isTemplateSchedulingOptionsSet || requireActiveVersion {
|
||||||
|
|||||||
@@ -16,13 +16,9 @@ import (
|
|||||||
|
|
||||||
func (r *RootCmd) templateDelete() *serpent.Command {
|
func (r *RootCmd) templateDelete() *serpent.Command {
|
||||||
orgContext := NewOrganizationContext()
|
orgContext := NewOrganizationContext()
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "delete [name...]",
|
Use: "delete [name...]",
|
||||||
Short: "Delete templates",
|
Short: "Delete templates",
|
||||||
Middleware: serpent.Chain(
|
|
||||||
r.InitClient(client),
|
|
||||||
),
|
|
||||||
Options: serpent.OptionSet{
|
Options: serpent.OptionSet{
|
||||||
cliui.SkipPromptOption(),
|
cliui.SkipPromptOption(),
|
||||||
},
|
},
|
||||||
@@ -32,7 +28,10 @@ func (r *RootCmd) templateDelete() *serpent.Command {
|
|||||||
templateNames = []string{}
|
templateNames = []string{}
|
||||||
templates = []codersdk.Template{}
|
templates = []codersdk.Template{}
|
||||||
)
|
)
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
organization, err := orgContext.Selected(inv, client)
|
organization, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
+4
-2
@@ -37,16 +37,18 @@ func (r *RootCmd) templateEdit() *serpent.Command {
|
|||||||
disableEveryone bool
|
disableEveryone bool
|
||||||
orgContext = NewOrganizationContext()
|
orgContext = NewOrganizationContext()
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "edit <template>",
|
Use: "edit <template>",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Short: "Edit the metadata of a template by name.",
|
Short: "Edit the metadata of a template by name.",
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
unsetAutostopRequirementDaysOfWeek := len(autostopRequirementDaysOfWeek) == 1 && autostopRequirementDaysOfWeek[0] == "none"
|
unsetAutostopRequirementDaysOfWeek := len(autostopRequirementDaysOfWeek) == 1 && autostopRequirementDaysOfWeek[0] == "none"
|
||||||
requiresScheduling := (len(autostopRequirementDaysOfWeek) > 0 && !unsetAutostopRequirementDaysOfWeek) ||
|
requiresScheduling := (len(autostopRequirementDaysOfWeek) > 0 && !unsetAutostopRequirementDaysOfWeek) ||
|
||||||
autostopRequirementWeeks > 0 ||
|
autostopRequirementWeeks > 0 ||
|
||||||
|
|||||||
+4
-4
@@ -16,15 +16,15 @@ func (r *RootCmd) templateList() *serpent.Command {
|
|||||||
cliui.JSONFormat(),
|
cliui.JSONFormat(),
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Short: "List all the templates available for the organization",
|
Short: "List all the templates available for the organization",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Middleware: serpent.Chain(
|
|
||||||
r.InitClient(client),
|
|
||||||
),
|
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
templates, err := client.Templates(inv.Context(), codersdk.TemplateFilter{})
|
templates, err := client.Templates(inv.Context(), codersdk.TemplateFilter{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ func (r *RootCmd) templatePresetsList() *serpent.Command {
|
|||||||
cliui.TableFormat([]TemplatePresetRow{}, defaultColumns),
|
cliui.TableFormat([]TemplatePresetRow{}, defaultColumns),
|
||||||
cliui.JSONFormat(),
|
cliui.JSONFormat(),
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
orgContext := NewOrganizationContext()
|
orgContext := NewOrganizationContext()
|
||||||
|
|
||||||
var templateVersion string
|
var templateVersion string
|
||||||
@@ -59,7 +58,6 @@ func (r *RootCmd) templatePresetsList() *serpent.Command {
|
|||||||
Use: "list <template>",
|
Use: "list <template>",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Short: "List all presets of the specified template. Defaults to the active template version.",
|
Short: "List all presets of the specified template. Defaults to the active template version.",
|
||||||
Options: serpent.OptionSet{
|
Options: serpent.OptionSet{
|
||||||
@@ -71,6 +69,10 @@ func (r *RootCmd) templatePresetsList() *serpent.Command {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
organization, err := orgContext.Selected(inv, client)
|
organization, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("get current organization: %w", err)
|
return xerrors.Errorf("get current organization: %w", err)
|
||||||
|
|||||||
+4
-2
@@ -23,13 +23,11 @@ func (r *RootCmd) templatePull() *serpent.Command {
|
|||||||
orgContext = NewOrganizationContext()
|
orgContext = NewOrganizationContext()
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "pull <name> [destination]",
|
Use: "pull <name> [destination]",
|
||||||
Short: "Download the active, latest, or specified version of a template to a path.",
|
Short: "Download the active, latest, or specified version of a template to a path.",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireRangeArgs(1, 2),
|
serpent.RequireRangeArgs(1, 2),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
var (
|
var (
|
||||||
@@ -37,6 +35,10 @@ func (r *RootCmd) templatePull() *serpent.Command {
|
|||||||
templateName = inv.Args[0]
|
templateName = inv.Args[0]
|
||||||
dest string
|
dest string
|
||||||
)
|
)
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if len(inv.Args) > 1 {
|
if len(inv.Args) > 1 {
|
||||||
dest = inv.Args[1]
|
dest = inv.Args[1]
|
||||||
|
|||||||
+4
-2
@@ -37,15 +37,17 @@ func (r *RootCmd) templatePush() *serpent.Command {
|
|||||||
activate bool
|
activate bool
|
||||||
orgContext = NewOrganizationContext()
|
orgContext = NewOrganizationContext()
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "push [template]",
|
Use: "push [template]",
|
||||||
Short: "Create or update a template from the current directory or as specified by flag",
|
Short: "Create or update a template from the current directory or as specified by flag",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireRangeArgs(0, 1),
|
serpent.RequireRangeArgs(0, 1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
uploadFlags.setWorkdir(workdir)
|
uploadFlags.setWorkdir(workdir)
|
||||||
|
|
||||||
organization, err := orgContext.Selected(inv, client)
|
organization, err := orgContext.Selected(inv, client)
|
||||||
|
|||||||
@@ -32,13 +32,9 @@ func (r *RootCmd) setArchiveTemplateVersion(archive bool) *serpent.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
orgContext := NewOrganizationContext()
|
orgContext := NewOrganizationContext()
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: presentVerb + " <template-name> [template-version-names...] ",
|
Use: presentVerb + " <template-name> [template-version-names...] ",
|
||||||
Short: strings.ToUpper(string(presentVerb[0])) + presentVerb[1:] + " a template version(s).",
|
Short: strings.ToUpper(string(presentVerb[0])) + presentVerb[1:] + " a template version(s).",
|
||||||
Middleware: serpent.Chain(
|
|
||||||
r.InitClient(client),
|
|
||||||
),
|
|
||||||
Options: serpent.OptionSet{
|
Options: serpent.OptionSet{
|
||||||
cliui.SkipPromptOption(),
|
cliui.SkipPromptOption(),
|
||||||
},
|
},
|
||||||
@@ -48,6 +44,11 @@ func (r *RootCmd) setArchiveTemplateVersion(archive bool) *serpent.Command {
|
|||||||
versions []codersdk.TemplateVersion
|
versions []codersdk.TemplateVersion
|
||||||
)
|
)
|
||||||
|
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
organization, err := orgContext.Selected(inv, client)
|
organization, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -100,14 +101,10 @@ func (r *RootCmd) setArchiveTemplateVersion(archive bool) *serpent.Command {
|
|||||||
|
|
||||||
func (r *RootCmd) archiveTemplateVersions() *serpent.Command {
|
func (r *RootCmd) archiveTemplateVersions() *serpent.Command {
|
||||||
var all serpent.Bool
|
var all serpent.Bool
|
||||||
client := new(codersdk.Client)
|
|
||||||
orgContext := NewOrganizationContext()
|
orgContext := NewOrganizationContext()
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "archive [template-name...] ",
|
Use: "archive [template-name...] ",
|
||||||
Short: "Archive unused or failed template versions from a given template(s)",
|
Short: "Archive unused or failed template versions from a given template(s)",
|
||||||
Middleware: serpent.Chain(
|
|
||||||
r.InitClient(client),
|
|
||||||
),
|
|
||||||
Options: serpent.OptionSet{
|
Options: serpent.OptionSet{
|
||||||
cliui.SkipPromptOption(),
|
cliui.SkipPromptOption(),
|
||||||
serpent.Option{
|
serpent.Option{
|
||||||
@@ -123,7 +120,10 @@ func (r *RootCmd) archiveTemplateVersions() *serpent.Command {
|
|||||||
templateNames = []string{}
|
templateNames = []string{}
|
||||||
templates = []codersdk.Template{}
|
templates = []codersdk.Template{}
|
||||||
)
|
)
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
organization, err := orgContext.Selected(inv, client)
|
organization, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ func (r *RootCmd) templateVersionsList() *serpent.Command {
|
|||||||
cliui.TableFormat([]templateVersionRow{}, defaultColumns),
|
cliui.TableFormat([]templateVersionRow{}, defaultColumns),
|
||||||
cliui.JSONFormat(),
|
cliui.JSONFormat(),
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
orgContext := NewOrganizationContext()
|
orgContext := NewOrganizationContext()
|
||||||
|
|
||||||
var includeArchived serpent.Bool
|
var includeArchived serpent.Bool
|
||||||
@@ -60,7 +59,6 @@ func (r *RootCmd) templateVersionsList() *serpent.Command {
|
|||||||
Use: "list <template>",
|
Use: "list <template>",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
func(next serpent.HandlerFunc) serpent.HandlerFunc {
|
func(next serpent.HandlerFunc) serpent.HandlerFunc {
|
||||||
return func(i *serpent.Invocation) error {
|
return func(i *serpent.Invocation) error {
|
||||||
// This is the only way to dynamically add the "archived"
|
// This is the only way to dynamically add the "archived"
|
||||||
@@ -95,6 +93,10 @@ func (r *RootCmd) templateVersionsList() *serpent.Command {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
organization, err := orgContext.Selected(inv, client)
|
organization, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("get current organization: %w", err)
|
return xerrors.Errorf("get current organization: %w", err)
|
||||||
@@ -177,15 +179,15 @@ func (r *RootCmd) templateVersionsPromote() *serpent.Command {
|
|||||||
templateVersionName string
|
templateVersionName string
|
||||||
orgContext = NewOrganizationContext()
|
orgContext = NewOrganizationContext()
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "promote --template=<template_name> --template-version=<template_version_name>",
|
Use: "promote --template=<template_name> --template-version=<template_version_name>",
|
||||||
Short: "Promote a template version to active.",
|
Short: "Promote a template version to active.",
|
||||||
Long: "Promote an existing template version to be the active version for the specified template.",
|
Long: "Promote an existing template version to be the active version for the specified template.",
|
||||||
Middleware: serpent.Chain(
|
|
||||||
r.InitClient(client),
|
|
||||||
),
|
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
organization, err := orgContext.Selected(inv, client)
|
organization, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
+15
-7
@@ -51,22 +51,24 @@ func (r *RootCmd) createToken() *serpent.Command {
|
|||||||
name string
|
name string
|
||||||
user string
|
user string
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "create",
|
Use: "create",
|
||||||
Short: "Create a token",
|
Short: "Create a token",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
userID := codersdk.Me
|
userID := codersdk.Me
|
||||||
if user != "" {
|
if user != "" {
|
||||||
userID = user
|
userID = user
|
||||||
}
|
}
|
||||||
|
|
||||||
var parsedLifetime time.Duration
|
var parsedLifetime time.Duration
|
||||||
var err error
|
|
||||||
|
|
||||||
tokenConfig, err := client.GetTokenConfig(inv.Context(), userID)
|
tokenConfig, err := client.GetTokenConfig(inv.Context(), userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -168,16 +170,19 @@ func (r *RootCmd) listTokens() *serpent.Command {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Short: "List tokens",
|
Short: "List tokens",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
tokens, err := client.Tokens(inv.Context(), codersdk.Me, codersdk.TokensFilter{
|
tokens, err := client.Tokens(inv.Context(), codersdk.Me, codersdk.TokensFilter{
|
||||||
IncludeAll: all,
|
IncludeAll: all,
|
||||||
})
|
})
|
||||||
@@ -222,16 +227,19 @@ func (r *RootCmd) listTokens() *serpent.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) removeToken() *serpent.Command {
|
func (r *RootCmd) removeToken() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "remove <name|id|token>",
|
Use: "remove <name|id|token>",
|
||||||
Aliases: []string{"delete"},
|
Aliases: []string{"delete"},
|
||||||
Short: "Delete a token",
|
Short: "Delete a token",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
token, err := client.APIKeyByName(inv.Context(), codersdk.Me, inv.Args[0])
|
token, err := client.APIKeyByName(inv.Context(), codersdk.Me, inv.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If it's a token, we need to extract the ID
|
// If it's a token, we need to extract the ID
|
||||||
|
|||||||
+5
-2
@@ -15,7 +15,6 @@ func (r *RootCmd) update() *serpent.Command {
|
|||||||
parameterFlags workspaceParameterFlags
|
parameterFlags workspaceParameterFlags
|
||||||
bflags buildFlags
|
bflags buildFlags
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "update <workspace>",
|
Use: "update <workspace>",
|
||||||
@@ -23,9 +22,13 @@ func (r *RootCmd) update() *serpent.Command {
|
|||||||
Long: "Use --always-prompt to change the parameter values of the workspace.",
|
Long: "Use --always-prompt to change the parameter values of the workspace.",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
+5
-2
@@ -26,15 +26,18 @@ func (r *RootCmd) userCreate() *serpent.Command {
|
|||||||
loginType string
|
loginType string
|
||||||
orgContext = NewOrganizationContext()
|
orgContext = NewOrganizationContext()
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "create",
|
Use: "create",
|
||||||
Short: "Create a new user.",
|
Short: "Create a new user.",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
organization, err := orgContext.Selected(inv, client)
|
organization, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
+4
-3
@@ -6,22 +6,23 @@ import (
|
|||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/coder/coder/v2/cli/cliui"
|
"github.com/coder/coder/v2/cli/cliui"
|
||||||
"github.com/coder/coder/v2/codersdk"
|
|
||||||
"github.com/coder/pretty"
|
"github.com/coder/pretty"
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) userDelete() *serpent.Command {
|
func (r *RootCmd) userDelete() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "delete <username|user_id>",
|
Use: "delete <username|user_id>",
|
||||||
Short: "Delete a user by username or user_id.",
|
Short: "Delete a user by username or user_id.",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
user, err := client.User(ctx, inv.Args[0])
|
user, err := client.User(ctx, inv.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("fetch user: %w", err)
|
return xerrors.Errorf("fetch user: %w", err)
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) userEditRoles() *serpent.Command {
|
func (r *RootCmd) userEditRoles() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
var givenRoles []string
|
var givenRoles []string
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "edit-roles <username|user_id>",
|
Use: "edit-roles <username|user_id>",
|
||||||
@@ -26,8 +25,13 @@ func (r *RootCmd) userEditRoles() *serpent.Command {
|
|||||||
Value: serpent.StringArrayOf(&givenRoles),
|
Value: serpent.StringArrayOf(&givenRoles),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Middleware: serpent.Chain(serpent.RequireNArgs(1), r.InitClient(client)),
|
Middleware: serpent.Chain(serpent.RequireNArgs(1)),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
|
||||||
user, err := client.User(ctx, inv.Args[0])
|
user, err := client.User(ctx, inv.Args[0])
|
||||||
|
|||||||
+10
-4
@@ -18,7 +18,6 @@ func (r *RootCmd) userList() *serpent.Command {
|
|||||||
cliui.TableFormat([]codersdk.User{}, []string{"username", "email", "created at", "status"}),
|
cliui.TableFormat([]codersdk.User{}, []string{"username", "email", "created at", "status"}),
|
||||||
cliui.JSONFormat(),
|
cliui.JSONFormat(),
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
var githubUserID int64
|
var githubUserID int64
|
||||||
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
@@ -27,7 +26,6 @@ func (r *RootCmd) userList() *serpent.Command {
|
|||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Options: serpent.OptionSet{
|
Options: serpent.OptionSet{
|
||||||
{
|
{
|
||||||
@@ -40,6 +38,11 @@ func (r *RootCmd) userList() *serpent.Command {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
req := codersdk.UsersRequest{}
|
req := codersdk.UsersRequest{}
|
||||||
if githubUserID != 0 {
|
if githubUserID != 0 {
|
||||||
req.Search = fmt.Sprintf("github_com_user_id:%d", githubUserID)
|
req.Search = fmt.Sprintf("github_com_user_id:%d", githubUserID)
|
||||||
@@ -69,7 +72,6 @@ func (r *RootCmd) userSingle() *serpent.Command {
|
|||||||
&userShowFormat{},
|
&userShowFormat{},
|
||||||
cliui.JSONFormat(),
|
cliui.JSONFormat(),
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "show <username|user_id|'me'>",
|
Use: "show <username|user_id|'me'>",
|
||||||
@@ -81,9 +83,13 @@ func (r *RootCmd) userSingle() *serpent.Command {
|
|||||||
),
|
),
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
user, err := client.User(inv.Context(), inv.Args[0])
|
user, err := client.User(inv.Context(), inv.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
+4
-3
@@ -33,8 +33,6 @@ func (r *RootCmd) createUserStatusCommand(sdkStatus codersdk.UserStatus) *serpen
|
|||||||
panic(fmt.Sprintf("%s is not supported", sdkStatus))
|
panic(fmt.Sprintf("%s is not supported", sdkStatus))
|
||||||
}
|
}
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
|
|
||||||
var columns []string
|
var columns []string
|
||||||
allColumns := []string{"username", "email", "created at", "status"}
|
allColumns := []string{"username", "email", "created at", "status"}
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
@@ -48,9 +46,12 @@ func (r *RootCmd) createUserStatusCommand(sdkStatus codersdk.UserStatus) *serpen
|
|||||||
),
|
),
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
identifier := inv.Args[0]
|
identifier := inv.Args[0]
|
||||||
if identifier == "" {
|
if identifier == "" {
|
||||||
return xerrors.Errorf("user identifier cannot be an empty string")
|
return xerrors.Errorf("user identifier cannot be an empty string")
|
||||||
|
|||||||
+5
-2
@@ -10,16 +10,19 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) whoami() *serpent.Command {
|
func (r *RootCmd) whoami() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Annotations: workspaceCommand,
|
Annotations: workspaceCommand,
|
||||||
Use: "whoami",
|
Use: "whoami",
|
||||||
Short: "Fetch authenticated user info for Coder deployment",
|
Short: "Fetch authenticated user info for Coder deployment",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
// Fetch the user info
|
// Fetch the user info
|
||||||
resp, err := client.User(ctx, codersdk.Me)
|
resp, err := client.User(ctx, codersdk.Me)
|
||||||
|
|||||||
@@ -77,10 +77,12 @@ func (r *RootCmd) externalWorkspaceCreate() *serpent.Command {
|
|||||||
cmd := r.Create(opts)
|
cmd := r.Create(opts)
|
||||||
cmd.Use = "create [workspace]"
|
cmd.Use = "create [workspace]"
|
||||||
cmd.Short = "Create a new external workspace"
|
cmd.Short = "Create a new external workspace"
|
||||||
cmd.Middleware = serpent.Chain(
|
newMiddlewares := []serpent.MiddlewareFunc{}
|
||||||
cmd.Middleware,
|
if cmd.Middleware != nil {
|
||||||
serpent.RequireNArgs(1),
|
newMiddlewares = append(newMiddlewares, cmd.Middleware)
|
||||||
)
|
}
|
||||||
|
newMiddlewares = append(newMiddlewares, serpent.RequireNArgs(1))
|
||||||
|
cmd.Middleware = serpent.Chain(newMiddlewares...)
|
||||||
|
|
||||||
for i := range cmd.Options {
|
for i := range cmd.Options {
|
||||||
if cmd.Options[i].Flag == "template" {
|
if cmd.Options[i].Flag == "template" {
|
||||||
@@ -93,7 +95,6 @@ func (r *RootCmd) externalWorkspaceCreate() *serpent.Command {
|
|||||||
|
|
||||||
// externalWorkspaceAgentInstructions prints the instructions for an external agent.
|
// externalWorkspaceAgentInstructions prints the instructions for an external agent.
|
||||||
func (r *RootCmd) externalWorkspaceAgentInstructions() *serpent.Command {
|
func (r *RootCmd) externalWorkspaceAgentInstructions() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
formatter := cliui.NewOutputFormatter(
|
formatter := cliui.NewOutputFormatter(
|
||||||
cliui.ChangeFormatterData(cliui.TextFormat(), func(data any) (any, error) {
|
cliui.ChangeFormatterData(cliui.TextFormat(), func(data any) (any, error) {
|
||||||
agent, ok := data.(externalAgent)
|
agent, ok := data.(externalAgent)
|
||||||
@@ -109,8 +110,13 @@ func (r *RootCmd) externalWorkspaceAgentInstructions() *serpent.Command {
|
|||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "agent-instructions [user/]workspace[.agent]",
|
Use: "agent-instructions [user/]workspace[.agent]",
|
||||||
Short: "Get the instructions for an external agent",
|
Short: "Get the instructions for an external agent",
|
||||||
Middleware: serpent.Chain(r.InitClient(client), serpent.RequireNArgs(1)),
|
Middleware: serpent.Chain(serpent.RequireNArgs(1)),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
workspace, workspaceAgent, _, err := agpl.GetWorkspaceAndAgent(inv.Context(), inv, client, false, inv.Args[0])
|
workspace, workspaceAgent, _, err := agpl.GetWorkspaceAndAgent(inv.Context(), inv, client, false, inv.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("find workspace and agent: %w", err)
|
return xerrors.Errorf("find workspace and agent: %w", err)
|
||||||
@@ -162,7 +168,6 @@ func (r *RootCmd) externalWorkspaceList() *serpent.Command {
|
|||||||
cliui.JSONFormat(),
|
cliui.JSONFormat(),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Annotations: map[string]string{
|
Annotations: map[string]string{
|
||||||
"workspaces": "",
|
"workspaces": "",
|
||||||
@@ -172,9 +177,13 @@ func (r *RootCmd) externalWorkspaceList() *serpent.Command {
|
|||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
baseFilter := filter.Filter()
|
baseFilter := filter.Filter()
|
||||||
|
|
||||||
if baseFilter.FilterQuery == "" {
|
if baseFilter.FilterQuery == "" {
|
||||||
|
|||||||
@@ -36,15 +36,16 @@ func (r *RootCmd) featuresList() *serpent.Command {
|
|||||||
columns []string
|
columns []string
|
||||||
outputFormat string
|
outputFormat string
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
entitlements, err := client.Entitlements(inv.Context())
|
entitlements, err := client.Entitlements(inv.Context())
|
||||||
var apiError *codersdk.Error
|
var apiError *codersdk.Error
|
||||||
if errors.As(err, &apiError) && apiError.StatusCode() == http.StatusNotFound {
|
if errors.As(err, &apiError) && apiError.StatusCode() == http.StatusNotFound {
|
||||||
|
|||||||
@@ -19,16 +19,18 @@ func (r *RootCmd) groupCreate() *serpent.Command {
|
|||||||
orgContext = agpl.NewOrganizationContext()
|
orgContext = agpl.NewOrganizationContext()
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "create <name>",
|
Use: "create <name>",
|
||||||
Short: "Create a user group",
|
Short: "Create a user group",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
org, err := orgContext.Selected(inv, client)
|
org, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -7,26 +7,27 @@ import (
|
|||||||
|
|
||||||
agpl "github.com/coder/coder/v2/cli"
|
agpl "github.com/coder/coder/v2/cli"
|
||||||
"github.com/coder/coder/v2/cli/cliui"
|
"github.com/coder/coder/v2/cli/cliui"
|
||||||
"github.com/coder/coder/v2/codersdk"
|
|
||||||
"github.com/coder/pretty"
|
"github.com/coder/pretty"
|
||||||
"github.com/coder/serpent"
|
"github.com/coder/serpent"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *RootCmd) groupDelete() *serpent.Command {
|
func (r *RootCmd) groupDelete() *serpent.Command {
|
||||||
orgContext := agpl.NewOrganizationContext()
|
orgContext := agpl.NewOrganizationContext()
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "delete <name>",
|
Use: "delete <name>",
|
||||||
Short: "Delete a user group",
|
Short: "Delete a user group",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
var (
|
var (
|
||||||
ctx = inv.Context()
|
ctx = inv.Context()
|
||||||
groupName = inv.Args[0]
|
groupName = inv.Args[0]
|
||||||
)
|
)
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
org, err := orgContext.Selected(inv, client)
|
org, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -24,19 +24,21 @@ func (r *RootCmd) groupEdit() *serpent.Command {
|
|||||||
rmUsers []string
|
rmUsers []string
|
||||||
orgContext = agpl.NewOrganizationContext()
|
orgContext = agpl.NewOrganizationContext()
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "edit <name>",
|
Use: "edit <name>",
|
||||||
Short: "Edit a user group",
|
Short: "Edit a user group",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
var (
|
var (
|
||||||
ctx = inv.Context()
|
ctx = inv.Context()
|
||||||
groupName = inv.Args[0]
|
groupName = inv.Args[0]
|
||||||
)
|
)
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
org, err := orgContext.Selected(inv, client)
|
org, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -20,16 +20,18 @@ func (r *RootCmd) groupList() *serpent.Command {
|
|||||||
)
|
)
|
||||||
orgContext := agpl.NewOrganizationContext()
|
orgContext := agpl.NewOrganizationContext()
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Short: "List user groups",
|
Short: "List user groups",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
org, err := orgContext.Selected(inv, client)
|
org, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -42,16 +42,18 @@ func (r *RootCmd) licenseAdd() *serpent.Command {
|
|||||||
license string
|
license string
|
||||||
debug bool
|
debug bool
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "add [-f file | -l license]",
|
Use: "add [-f file | -l license]",
|
||||||
Short: "Add license to Coder deployment",
|
Short: "Add license to Coder deployment",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
var err error
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case filename != "" && license != "":
|
case filename != "" && license != "":
|
||||||
return xerrors.New("only one of (--file, --license) may be specified")
|
return xerrors.New("only one of (--file, --license) may be specified")
|
||||||
@@ -137,16 +139,19 @@ func validJWT(s string) error {
|
|||||||
|
|
||||||
func (r *RootCmd) licensesList() *serpent.Command {
|
func (r *RootCmd) licensesList() *serpent.Command {
|
||||||
formatter := cliutil.NewLicenseFormatter()
|
formatter := cliutil.NewLicenseFormatter()
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Short: "List licenses (including expired)",
|
Short: "List licenses (including expired)",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
licenses, err := client.Licenses(inv.Context())
|
licenses, err := client.Licenses(inv.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -170,16 +175,19 @@ func (r *RootCmd) licensesList() *serpent.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) licenseDelete() *serpent.Command {
|
func (r *RootCmd) licenseDelete() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "delete <id>",
|
Use: "delete <id>",
|
||||||
Short: "Delete license by ID",
|
Short: "Delete license by ID",
|
||||||
Aliases: []string{"del"},
|
Aliases: []string{"del"},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
id, err := strconv.ParseInt(inv.Args[0], 10, 32)
|
id, err := strconv.ParseInt(inv.Args[0], 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("license ID must be an integer: %s", inv.Args[0])
|
return xerrors.Errorf("license ID must be an integer: %s", inv.Args[0])
|
||||||
|
|||||||
@@ -38,16 +38,19 @@ func (r *RootCmd) prebuilds() *serpent.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) pausePrebuilds() *serpent.Command {
|
func (r *RootCmd) pausePrebuilds() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "pause",
|
Use: "pause",
|
||||||
Short: "Pause prebuilds",
|
Short: "Pause prebuilds",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
err := client.PutPrebuildsSettings(inv.Context(), codersdk.PrebuildsSettings{
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.PutPrebuildsSettings(inv.Context(), codersdk.PrebuildsSettings{
|
||||||
ReconciliationPaused: true,
|
ReconciliationPaused: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -62,16 +65,19 @@ func (r *RootCmd) pausePrebuilds() *serpent.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) resumePrebuilds() *serpent.Command {
|
func (r *RootCmd) resumePrebuilds() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "resume",
|
Use: "resume",
|
||||||
Short: "Resume prebuilds",
|
Short: "Resume prebuilds",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
err := client.PutPrebuildsSettings(inv.Context(), codersdk.PrebuildsSettings{
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.PutPrebuildsSettings(inv.Context(), codersdk.PrebuildsSettings{
|
||||||
ReconciliationPaused: false,
|
ReconciliationPaused: false,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -53,19 +53,16 @@ func (r *RootCmd) provisionerDaemonStart() *serpent.Command {
|
|||||||
prometheusAddress string
|
prometheusAddress string
|
||||||
)
|
)
|
||||||
orgContext := agpl.NewOrganizationContext()
|
orgContext := agpl.NewOrganizationContext()
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "start",
|
Use: "start",
|
||||||
Short: "Run a provisioner daemon",
|
Short: "Run a provisioner daemon",
|
||||||
Middleware: serpent.Chain(
|
|
||||||
// disable checks and warnings because this command starts a daemon; it is
|
|
||||||
// not meant for humans typing commands. Furthermore, the checks are
|
|
||||||
// incompatible with PSK auth that this command uses
|
|
||||||
r.InitClient(client),
|
|
||||||
),
|
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
ctx, cancel := context.WithCancel(inv.Context())
|
ctx, cancel := context.WithCancel(inv.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
stopCtx, stopCancel := inv.SignalNotifyContext(ctx, agpl.StopSignalsNoInterrupt...)
|
stopCtx, stopCancel := inv.SignalNotifyContext(ctx, agpl.StopSignalsNoInterrupt...)
|
||||||
defer stopCancel()
|
defer stopCancel()
|
||||||
|
|||||||
@@ -37,16 +37,18 @@ func (r *RootCmd) provisionerKeysCreate() *serpent.Command {
|
|||||||
rawTags []string
|
rawTags []string
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "create <name>",
|
Use: "create <name>",
|
||||||
Short: "Create a new provisioner key",
|
Short: "Create a new provisioner key",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
org, err := orgContext.Selected(inv, client)
|
org, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -100,17 +102,19 @@ func (r *RootCmd) provisionerKeysList() *serpent.Command {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Short: "List provisioner keys in an organization",
|
Short: "List provisioner keys in an organization",
|
||||||
Aliases: []string{"ls"},
|
Aliases: []string{"ls"},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
org, err := orgContext.Selected(inv, client)
|
org, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -147,16 +151,18 @@ func (r *RootCmd) provisionerKeysList() *serpent.Command {
|
|||||||
func (r *RootCmd) provisionerKeysDelete() *serpent.Command {
|
func (r *RootCmd) provisionerKeysDelete() *serpent.Command {
|
||||||
orgContext := agpl.NewOrganizationContext()
|
orgContext := agpl.NewOrganizationContext()
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "delete <name>",
|
Use: "delete <name>",
|
||||||
Short: "Delete a provisioner key",
|
Short: "Delete a provisioner key",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
org, err := orgContext.Selected(inv, client)
|
org, err := orgContext.Selected(inv, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -42,17 +42,19 @@ func (r *RootCmd) workspaceProxy() *serpent.Command {
|
|||||||
|
|
||||||
func (r *RootCmd) regenerateProxyToken() *serpent.Command {
|
func (r *RootCmd) regenerateProxyToken() *serpent.Command {
|
||||||
formatter := newUpdateProxyResponseFormatter()
|
formatter := newUpdateProxyResponseFormatter()
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "regenerate-token <name|id>",
|
Use: "regenerate-token <name|id>",
|
||||||
Short: "Regenerate a workspace proxy authentication token. " +
|
Short: "Regenerate a workspace proxy authentication token. " +
|
||||||
"This will invalidate the existing authentication token.",
|
"This will invalidate the existing authentication token.",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
formatter.primaryAccessURL = client.URL.String()
|
formatter.primaryAccessURL = client.URL.String()
|
||||||
// This is cheeky, but you can also use a uuid string in
|
// This is cheeky, but you can also use a uuid string in
|
||||||
// 'DeleteWorkspaceProxyByName' and it will work.
|
// 'DeleteWorkspaceProxyByName' and it will work.
|
||||||
@@ -112,16 +114,18 @@ func (r *RootCmd) patchProxy() *serpent.Command {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "edit <name|id>",
|
Use: "edit <name|id>",
|
||||||
Short: "Edit a workspace proxy",
|
Short: "Edit a workspace proxy",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if proxyIcon == "" && displayName == "" && proxyName == "" {
|
if proxyIcon == "" && displayName == "" && proxyName == "" {
|
||||||
_ = inv.Command.HelpHandler(inv)
|
_ = inv.Command.HelpHandler(inv)
|
||||||
return xerrors.Errorf("specify at least one field to update")
|
return xerrors.Errorf("specify at least one field to update")
|
||||||
@@ -187,7 +191,6 @@ func (r *RootCmd) patchProxy() *serpent.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *RootCmd) deleteProxy() *serpent.Command {
|
func (r *RootCmd) deleteProxy() *serpent.Command {
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "delete <name|id>",
|
Use: "delete <name|id>",
|
||||||
Short: "Delete a workspace proxy",
|
Short: "Delete a workspace proxy",
|
||||||
@@ -196,10 +199,13 @@ func (r *RootCmd) deleteProxy() *serpent.Command {
|
|||||||
},
|
},
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(1),
|
serpent.RequireNArgs(1),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
wsproxy, err := client.WorkspaceProxyByName(ctx, inv.Args[0])
|
wsproxy, err := client.WorkspaceProxyByName(ctx, inv.Args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -244,18 +250,19 @@ func (r *RootCmd) createProxy() *serpent.Command {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "create",
|
Use: "create",
|
||||||
Short: "Create a workspace proxy",
|
Short: "Create a workspace proxy",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
formatter.primaryAccessURL = client.URL.String()
|
formatter.primaryAccessURL = client.URL.String()
|
||||||
var err error
|
|
||||||
if proxyName == "" && !noPrompts {
|
if proxyName == "" && !noPrompts {
|
||||||
proxyName, err = cliui.Prompt(inv, cliui.PromptOptions{
|
proxyName, err = cliui.Prompt(inv, cliui.PromptOptions{
|
||||||
Text: "Proxy Name:",
|
Text: "Proxy Name:",
|
||||||
@@ -362,17 +369,19 @@ func (r *RootCmd) listProxies() *serpent.Command {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
client := new(codersdk.Client)
|
|
||||||
cmd := &serpent.Command{
|
cmd := &serpent.Command{
|
||||||
Use: "ls",
|
Use: "ls",
|
||||||
Aliases: []string{"list"},
|
Aliases: []string{"list"},
|
||||||
Short: "List all workspace proxies",
|
Short: "List all workspace proxies",
|
||||||
Middleware: serpent.Chain(
|
Middleware: serpent.Chain(
|
||||||
serpent.RequireNArgs(0),
|
serpent.RequireNArgs(0),
|
||||||
r.InitClient(client),
|
|
||||||
),
|
),
|
||||||
Handler: func(inv *serpent.Invocation) error {
|
Handler: func(inv *serpent.Invocation) error {
|
||||||
ctx := inv.Context()
|
ctx := inv.Context()
|
||||||
|
client, err := r.InitClient(inv)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
proxies, err := client.WorkspaceProxies(ctx)
|
proxies, err := client.WorkspaceProxies(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("list workspace proxies: %w", err)
|
return xerrors.Errorf("list workspace proxies: %w", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user