Files
coder/enterprise/cli/aigateway.go
T
Paweł Banaszewski 148d6ca5c5 remove Coderd infix
2026-06-02 14:35:38 +00:00

179 lines
4.2 KiB
Go

package cli
import (
"context"
"fmt"
"time"
"golang.org/x/xerrors"
"github.com/coder/coder/v2/cli/cliui"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/serpent"
)
func (r *RootCmd) aiGateway() *serpent.Command {
return &serpent.Command{
Use: "gateway",
Short: "Manage AI Gateway.",
Handler: func(inv *serpent.Invocation) error {
return inv.Command.HelpHandler(inv)
},
Children: []*serpent.Command{
r.aiGatewayKeys(),
},
}
}
func (r *RootCmd) aiGatewayKeys() *serpent.Command {
return &serpent.Command{
Use: "keys",
Short: "Manage AI Gateway keys.",
Handler: func(inv *serpent.Invocation) error {
return inv.Command.HelpHandler(inv)
},
Children: []*serpent.Command{
r.aiGatewayKeysCreate(),
r.aiGatewayKeysDelete(),
r.aiGatewayKeysList(),
},
}
}
func (r *RootCmd) aiGatewayKeysCreate() *serpent.Command {
return &serpent.Command{
Use: "create <name>",
Short: "Create an AI Gateway key",
Middleware: serpent.Chain(
serpent.RequireNArgs(1),
),
Handler: func(inv *serpent.Invocation) error {
client, err := r.InitClient(inv)
if err != nil {
return err
}
res, err := client.CreateAIGatewayKey(inv.Context(), codersdk.CreateAIGatewayKeyRequest{
Name: inv.Args[0],
})
if err != nil {
return xerrors.Errorf("create AI Gateway key %q: %w", inv.Args[0], err)
}
_, _ = fmt.Fprintf(
inv.Stdout,
"Successfully created AI Gateway key %s (ID: %s, Prefix: %s).\nSave this authentication token, it will not be shown again.\n\n%s\n",
cliui.Keyword(res.Name),
res.ID,
res.KeyPrefix,
cliui.Keyword(res.Key),
)
return nil
},
}
}
func (r *RootCmd) aiGatewayKeysList() *serpent.Command {
formatter := cliui.NewOutputFormatter(
cliui.TableFormat([]codersdk.AIGatewayKey{}, []string{"id", "name", "key prefix", "last used at", "created at"}),
cliui.JSONFormat(),
)
cmd := &serpent.Command{
Use: "list",
Short: "List AI Gateway keys",
Middleware: serpent.Chain(
serpent.RequireNArgs(0),
),
Handler: func(inv *serpent.Invocation) error {
client, err := r.InitClient(inv)
if err != nil {
return err
}
keys, err := client.ListAIGatewayKeys(inv.Context())
if err != nil {
return xerrors.Errorf("list AI Gateway keys: %w", err)
}
out, err := formatter.Format(inv.Context(), keys)
if err != nil {
return xerrors.Errorf("format AI Gateway keys: %w", err)
}
if out == "" {
cliui.Info(inv.Stderr, "No AI Gateway keys found.")
return nil
}
_, err = fmt.Fprintln(inv.Stdout, out)
return err
},
}
formatter.AttachOptions(&cmd.Options)
return cmd
}
func (r *RootCmd) aiGatewayKeysDelete() *serpent.Command {
cmd := &serpent.Command{
Use: "delete <id>",
Short: "Delete an AI Gateway key",
Middleware: serpent.Chain(
serpent.RequireNArgs(1),
),
Options: serpent.OptionSet{
cliui.SkipPromptOption(),
},
Handler: func(inv *serpent.Invocation) error {
client, err := r.InitClient(inv)
if err != nil {
return err
}
key, err := aiGatewayKeyByNameOrID(inv.Context(), client, inv.Args[0])
if err != nil {
return err
}
_, err = cliui.Prompt(inv, cliui.PromptOptions{
Text: fmt.Sprintf("Are you sure you want to delete AI Gateway key %s (ID: %s, Prefix: %s)?", cliui.Keyword(key.Name), key.ID, key.KeyPrefix),
IsConfirm: true,
Default: cliui.ConfirmNo,
})
if err != nil {
return err
}
err = client.DeleteAIGatewayKey(inv.Context(), key.ID)
if err != nil {
return xerrors.Errorf("delete AI Gateway key %q: %w", key.Name, err)
}
_, _ = fmt.Fprintf(inv.Stdout, "Deleted AI Gateway key %s at %s.\n", cliui.Keyword(key.Name), cliui.Timestamp(time.Now()))
return nil
},
}
return cmd
}
func aiGatewayKeyByNameOrID(ctx context.Context, client *codersdk.Client, nameOrID string) (codersdk.AIGatewayKey, error) {
keys, err := client.ListAIGatewayKeys(ctx)
if err != nil {
return codersdk.AIGatewayKey{}, xerrors.Errorf("list AI Gateway keys: %w", err)
}
for _, key := range keys {
if key.ID.String() == nameOrID {
return key, nil
}
}
for _, key := range keys {
if key.Name == nameOrID {
return key, nil
}
}
return codersdk.AIGatewayKey{}, xerrors.Errorf("AI Gateway key %q not found", nameOrID)
}