fix: improve provisioner key cli usability (#14834)

What this changes:
- Unhides the `--key` flag on provisioner start
- Deprecates and hides `provisionerd` command group in favor of
`provisioner(s)`
- Removes org id from `coder provisioner keys list`
This commit is contained in:
Garrett Delfosse
2024-09-27 10:34:41 -05:00
committed by GitHub
parent 62047e5f68
commit 5cc5bbea04
30 changed files with 329 additions and 131 deletions
+7 -4
View File
@@ -11885,10 +11885,7 @@ const docTemplate = `{
"format": "uuid"
},
"tags": {
"type": "object",
"additionalProperties": {
"type": "string"
}
"$ref": "#/definitions/codersdk.ProvisionerKeyTags"
}
}
},
@@ -11906,6 +11903,12 @@ const docTemplate = `{
}
}
},
"codersdk.ProvisionerKeyTags": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"codersdk.ProvisionerLogLevel": {
"type": "string",
"enum": [
+7 -4
View File
@@ -10731,10 +10731,7 @@
"format": "uuid"
},
"tags": {
"type": "object",
"additionalProperties": {
"type": "string"
}
"$ref": "#/definitions/codersdk.ProvisionerKeyTags"
}
}
},
@@ -10752,6 +10749,12 @@
}
}
},
"codersdk.ProvisionerKeyTags": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"codersdk.ProvisionerLogLevel": {
"type": "string",
"enum": ["debug"],
+16 -5
View File
@@ -7,6 +7,7 @@ import (
"io"
"net/http"
"net/http/cookiejar"
"strings"
"time"
"github.com/google/uuid"
@@ -274,12 +275,22 @@ func (c *Client) ServeProvisionerDaemon(ctx context.Context, req ServeProvisione
return proto.NewDRPCProvisionerDaemonClient(drpc.MultiplexedConn(session)), nil
}
type ProvisionerKeyTags map[string]string
func (p ProvisionerKeyTags) String() string {
tags := []string{}
for key, value := range p {
tags = append(tags, fmt.Sprintf("%s=%s", key, value))
}
return strings.Join(tags, " ")
}
type ProvisionerKey struct {
ID uuid.UUID `json:"id" table:"-" format:"uuid"`
CreatedAt time.Time `json:"created_at" table:"created at" format:"date-time"`
OrganizationID uuid.UUID `json:"organization" table:"organization id" format:"uuid"`
Name string `json:"name" table:"name,default_sort"`
Tags map[string]string `json:"tags" table:"tags"`
ID uuid.UUID `json:"id" table:"-" format:"uuid"`
CreatedAt time.Time `json:"created_at" table:"created at" format:"date-time"`
OrganizationID uuid.UUID `json:"organization" table:"-" format:"uuid"`
Name string `json:"name" table:"name,default_sort"`
Tags ProvisionerKeyTags `json:"tags" table:"tags"`
// HashedSecret - never include the access token in the API response
}
+3 -3
View File
@@ -26,7 +26,7 @@ For example, running 30 provisioner containers will allow 30 users to start
workspaces at the same time.
Provisioners are started with the
[coder provisionerd start](../reference/cli/provisionerd_start.md) command.
[coder provisionerd start](../reference/cli/provisioner_start.md) command.
## Authentication
@@ -49,7 +49,7 @@ the [Helm example](#example-running-an-external-provisioner-with-helm) below.
Provisioners can broadly be categorized by scope: `organization` or `user`. The
scope of a provisioner can be specified with
[`-tag=scope=<scope>`](../reference/cli/provisionerd_start.md#t---tag) when
[`-tag=scope=<scope>`](../reference/cli/provisioner_start.md#t---tag) when
starting the provisioner daemon. Only users with at least the
[Template Admin](../admin/users.md#roles) role or higher may create
organization-scoped provisioner daemons.
@@ -59,7 +59,7 @@ There are two exceptions:
- [Built-in provisioners](../reference/cli/server.md#provisioner-daemons) are
always organization-scoped.
- External provisioners started using a
[pre-shared key (PSK)](../reference/cli/provisionerd_start.md#psk) are always
[pre-shared key (PSK)](../reference/cli/provisioner_start.md#psk) are always
organization-scoped.
### Organization-Scoped Provisioners
+12 -12
View File
@@ -921,34 +921,34 @@
"path": "reference/cli/port-forward.md"
},
{
"title": "provisionerd",
"title": "provisioner",
"description": "Manage provisioner daemons",
"path": "reference/cli/provisionerd.md"
"path": "reference/cli/provisioner.md"
},
{
"title": "provisionerd keys",
"title": "provisioner keys",
"description": "Manage provisioner keys",
"path": "reference/cli/provisionerd_keys.md"
"path": "reference/cli/provisioner_keys.md"
},
{
"title": "provisionerd keys create",
"title": "provisioner keys create",
"description": "Create a new provisioner key",
"path": "reference/cli/provisionerd_keys_create.md"
"path": "reference/cli/provisioner_keys_create.md"
},
{
"title": "provisionerd keys delete",
"title": "provisioner keys delete",
"description": "Delete a provisioner key",
"path": "reference/cli/provisionerd_keys_delete.md"
"path": "reference/cli/provisioner_keys_delete.md"
},
{
"title": "provisionerd keys list",
"title": "provisioner keys list",
"description": "List provisioner keys in an organization",
"path": "reference/cli/provisionerd_keys_list.md"
"path": "reference/cli/provisioner_keys_list.md"
},
{
"title": "provisionerd start",
"title": "provisioner start",
"description": "Run a provisioner daemon",
"path": "reference/cli/provisionerd_start.md"
"path": "reference/cli/provisioner_start.md"
},
{
"title": "publickey",
+31 -31
View File
@@ -1609,15 +1609,15 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/provisi
Status Code **200**
| Name | Type | Required | Restrictions | Description |
| ------------------- | ----------------- | -------- | ------------ | ----------- |
| `[array item]` | array | false | | |
| `» created_at` | string(date-time) | false | | |
| `» id` | string(uuid) | false | | |
| `» name` | string | false | | |
| `» organization` | string(uuid) | false | | |
| `» tags` | object | false | | |
| `»» [any property]` | string | false | | |
| Name | Type | Required | Restrictions | Description |
| ------------------- | -------------------------------------------------------------------- | -------- | ------------ | ----------- |
| `[array item]` | array | false | | |
| `» created_at` | string(date-time) | false | | |
| `» id` | string(uuid) | false | | |
| `» name` | string | false | | |
| `» organization` | string(uuid) | false | | |
| `» tags` | [codersdk.ProvisionerKeyTags](schemas.md#codersdkprovisionerkeytags) | false | | |
| `»» [any property]` | string | false | | |
To perform this operation, you must be authenticated. [Learn more](authentication.md).
@@ -1725,28 +1725,28 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/provisi
Status Code **200**
| Name | Type | Required | Restrictions | Description |
| -------------------- | ------------------------------------------------------------ | -------- | ------------ | ----------- |
| `[array item]` | array | false | | |
| `» daemons` | array | false | | |
| `»» api_version` | string | false | | |
| `»» created_at` | string(date-time) | false | | |
| `»» id` | string(uuid) | false | | |
| `»» key_id` | string(uuid) | false | | |
| `»» last_seen_at` | string(date-time) | false | | |
| `»» name` | string | false | | |
| `»» organization_id` | string(uuid) | false | | |
| `»» provisioners` | array | false | | |
| `»» tags` | object | false | | |
| `»»» [any property]` | string | false | | |
| `»» version` | string | false | | |
| `» key` | [codersdk.ProvisionerKey](schemas.md#codersdkprovisionerkey) | false | | |
| `»» created_at` | string(date-time) | false | | |
| `»» id` | string(uuid) | false | | |
| `»» name` | string | false | | |
| `»» organization` | string(uuid) | false | | |
| `»» tags` | object | false | | |
| `»»» [any property]` | string | false | | |
| Name | Type | Required | Restrictions | Description |
| -------------------- | -------------------------------------------------------------------- | -------- | ------------ | ----------- |
| `[array item]` | array | false | | |
| `» daemons` | array | false | | |
| `»» api_version` | string | false | | |
| `»» created_at` | string(date-time) | false | | |
| `»» id` | string(uuid) | false | | |
| `»» key_id` | string(uuid) | false | | |
| `»» last_seen_at` | string(date-time) | false | | |
| `»» name` | string | false | | |
| `»» organization_id` | string(uuid) | false | | |
| `»» provisioners` | array | false | | |
| `»» tags` | object | false | | |
| `»»» [any property]` | string | false | | |
| `»» version` | string | false | | |
| `» key` | [codersdk.ProvisionerKey](schemas.md#codersdkprovisionerkey) | false | | |
| `»» created_at` | string(date-time) | false | | |
| `»» id` | string(uuid) | false | | |
| `»» name` | string | false | | |
| `»» organization` | string(uuid) | false | | |
| `»» tags` | [codersdk.ProvisionerKeyTags](schemas.md#codersdkprovisionerkeytags) | false | | |
| `»»» [any property]` | string | false | | |
To perform this operation, you must be authenticated. [Learn more](authentication.md).
+22 -8
View File
@@ -4176,14 +4176,13 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
### Properties
| Name | Type | Required | Restrictions | Description |
| ------------------ | ------ | -------- | ------------ | ----------- |
| `created_at` | string | false | | |
| `id` | string | false | | |
| `name` | string | false | | |
| `organization` | string | false | | |
| `tags` | object | false | | |
| » `[any property]` | string | false | | |
| Name | Type | Required | Restrictions | Description |
| -------------- | ---------------------------------------------------------- | -------- | ------------ | ----------- |
| `created_at` | string | false | | |
| `id` | string | false | | |
| `name` | string | false | | |
| `organization` | string | false | | |
| `tags` | [codersdk.ProvisionerKeyTags](#codersdkprovisionerkeytags) | false | | |
## codersdk.ProvisionerKeyDaemons
@@ -4226,6 +4225,21 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
| `daemons` | array of [codersdk.ProvisionerDaemon](#codersdkprovisionerdaemon) | false | | |
| `key` | [codersdk.ProvisionerKey](#codersdkprovisionerkey) | false | | |
## codersdk.ProvisionerKeyTags
```json
{
"property1": "string",
"property2": "string"
}
```
### Properties
| Name | Type | Required | Restrictions | Description |
| ---------------- | ------ | -------- | ------------ | ----------- |
| `[any property]` | string | false | | |
## codersdk.ProvisionerLogLevel
```json
+1 -1
View File
@@ -66,7 +66,7 @@ Coder — A tool for provisioning self-hosted development environments with Terr
| [<code>features</code>](./features.md) | List Enterprise features |
| [<code>licenses</code>](./licenses.md) | Add, delete, and list licenses |
| [<code>groups</code>](./groups.md) | Manage groups |
| [<code>provisionerd</code>](./provisionerd.md) | Manage provisioner daemons |
| [<code>provisioner</code>](./provisioner.md) | Manage provisioner daemons |
## Options
+22
View File
@@ -0,0 +1,22 @@
<!-- DO NOT EDIT | GENERATED CONTENT -->
# provisioner
Manage provisioner daemons
Aliases:
- provisioners
## Usage
```console
coder provisioner
```
## Subcommands
| Name | Purpose |
| -------------------------------------------- | ------------------------ |
| [<code>start</code>](./provisioner_start.md) | Run a provisioner daemon |
| [<code>keys</code>](./provisioner_keys.md) | Manage provisioner keys |
+23
View File
@@ -0,0 +1,23 @@
<!-- DO NOT EDIT | GENERATED CONTENT -->
# provisioner keys
Manage provisioner keys
Aliases:
- key
## Usage
```console
coder provisioner keys
```
## Subcommands
| Name | Purpose |
| --------------------------------------------------- | ---------------------------------------- |
| [<code>create</code>](./provisioner_keys_create.md) | Create a new provisioner key |
| [<code>list</code>](./provisioner_keys_list.md) | List provisioner keys in an organization |
| [<code>delete</code>](./provisioner_keys_delete.md) | Delete a provisioner key |
@@ -1,13 +1,13 @@
<!-- DO NOT EDIT | GENERATED CONTENT -->
# provisionerd keys create
# provisioner keys create
Create a new provisioner key
## Usage
```console
coder provisionerd keys create [flags] <name>
coder provisioner keys create [flags] <name>
```
## Options
@@ -1,6 +1,6 @@
<!-- DO NOT EDIT | GENERATED CONTENT -->
# provisionerd keys delete
# provisioner keys delete
Delete a provisioner key
@@ -11,7 +11,7 @@ Aliases:
## Usage
```console
coder provisionerd keys delete [flags] <name>
coder provisioner keys delete [flags] <name>
```
## Options
@@ -1,6 +1,6 @@
<!-- DO NOT EDIT | GENERATED CONTENT -->
# provisionerd keys list
# provisioner keys list
List provisioner keys in an organization
@@ -11,7 +11,7 @@ Aliases:
## Usage
```console
coder provisionerd keys list [flags]
coder provisioner keys list [flags]
```
## Options
@@ -1,13 +1,13 @@
<!-- DO NOT EDIT | GENERATED CONTENT -->
# provisionerd start
# provisioner start
Run a provisioner daemon
## Usage
```console
coder provisionerd start [flags]
coder provisioner start [flags]
```
## Options
@@ -60,6 +60,15 @@ Deprecated and ignored.
Pre-shared key to authenticate with Coder server.
### --key
| | |
| ----------- | ------------------------------------------ |
| Type | <code>string</code> |
| Environment | <code>$CODER_PROVISIONER_DAEMON_KEY</code> |
Provisioner key to authenticate with Coder server.
### --name
| | |
-22
View File
@@ -1,22 +0,0 @@
<!-- DO NOT EDIT | GENERATED CONTENT -->
# provisionerd
Manage provisioner daemons
Aliases:
- provisioner
## Usage
```console
coder provisionerd
```
## Subcommands
| Name | Purpose |
| --------------------------------------------- | ------------------------ |
| [<code>start</code>](./provisionerd_start.md) | Run a provisioner daemon |
| [<code>keys</code>](./provisionerd_keys.md) | Manage provisioner keys |
-23
View File
@@ -1,23 +0,0 @@
<!-- DO NOT EDIT | GENERATED CONTENT -->
# provisionerd keys
Manage provisioner keys
Aliases:
- key
## Usage
```console
coder provisionerd keys
```
## Subcommands
| Name | Purpose |
| ---------------------------------------------------- | ---------------------------------------- |
| [<code>create</code>](./provisionerd_keys_create.md) | Create a new provisioner key |
| [<code>list</code>](./provisionerd_keys_list.md) | List provisioner keys in an organization |
| [<code>delete</code>](./provisionerd_keys_delete.md) | Delete a provisioner key |
+20 -2
View File
@@ -4,12 +4,12 @@ import "github.com/coder/serpent"
func (r *RootCmd) provisionerDaemons() *serpent.Command {
cmd := &serpent.Command{
Use: "provisionerd",
Use: "provisioner",
Short: "Manage provisioner daemons",
Handler: func(inv *serpent.Invocation) error {
return inv.Command.HelpHandler(inv)
},
Aliases: []string{"provisioner"},
Aliases: []string{"provisioners"},
Children: []*serpent.Command{
r.provisionerDaemonStart(),
r.provisionerKeys(),
@@ -18,3 +18,21 @@ func (r *RootCmd) provisionerDaemons() *serpent.Command {
return cmd
}
// The provisionerd command group is deprecated and hidden but kept around
// for backwards compatibility with the start command.
func (r *RootCmd) provisionerd() *serpent.Command {
cmd := &serpent.Command{
Use: "provisionerd",
Short: "Manage provisioner daemons",
Handler: func(inv *serpent.Invocation) error {
return inv.Command.HelpHandler(inv)
},
Children: []*serpent.Command{
r.provisionerDaemonStart(),
},
Hidden: true,
}
return cmd
}
-1
View File
@@ -270,7 +270,6 @@ func (r *RootCmd) provisionerDaemonStart() *serpent.Command {
Env: "CODER_PROVISIONER_DAEMON_KEY",
Description: "Provisioner key to authenticate with Coder server.",
Value: serpent.StringOf(&provisionerKey),
Hidden: true,
}
cmd.Options = serpent.OptionSet{
{
+1 -1
View File
@@ -95,7 +95,7 @@ func (r *RootCmd) provisionerKeysList() *serpent.Command {
var (
orgContext = agpl.NewOrganizationContext()
formatter = cliui.NewOutputFormatter(
cliui.TableFormat([]codersdk.ProvisionerKey{}, nil),
cliui.TableFormat([]codersdk.ProvisionerKey{}, []string{"created at", "name", "tags"}),
cliui.JSONFormat(),
)
)
+2 -3
View File
@@ -41,7 +41,7 @@ func TestProvisionerKeys(t *testing.T) {
ctx := testutil.Context(t, testutil.WaitMedium)
inv, conf := newCLI(
t,
"provisioner", "keys", "create", name, "--tag", "foo=bar",
"provisioner", "keys", "create", name, "--tag", "foo=bar", "--tag", "my=way",
)
pty := ptytest.New(t)
@@ -73,11 +73,10 @@ func TestProvisionerKeys(t *testing.T) {
line = pty.ReadLine(ctx)
require.Contains(t, line, "NAME")
require.Contains(t, line, "CREATED AT")
require.Contains(t, line, "ORGANIZATION ID")
require.Contains(t, line, "TAGS")
line = pty.ReadLine(ctx)
require.Contains(t, line, strings.ToLower(name))
require.Contains(t, line, "map[foo:bar]")
require.Contains(t, line, "foo=bar my=way")
inv, conf = newCLI(
t,
+1
View File
@@ -17,6 +17,7 @@ func (r *RootCmd) enterpriseOnly() []*serpent.Command {
r.licenses(),
r.groups(),
r.provisionerDaemons(),
r.provisionerd(),
}
}
+1 -1
View File
@@ -17,7 +17,7 @@ SUBCOMMANDS:
features List Enterprise features
groups Manage groups
licenses Add, delete, and list licenses
provisionerd Manage provisioner daemons
provisioner Manage provisioner daemons
server Start a Coder server
GLOBAL OPTIONS:
+15
View File
@@ -0,0 +1,15 @@
coder v0.0.0-devel
USAGE:
coder provisioner
Manage provisioner daemons
Aliases: provisioners
SUBCOMMANDS:
keys Manage provisioner keys
start Run a provisioner daemon
———
Run `coder --help` for a list of global options.
@@ -0,0 +1,16 @@
coder v0.0.0-devel
USAGE:
coder provisioner keys
Manage provisioner keys
Aliases: key
SUBCOMMANDS:
create Create a new provisioner key
delete Delete a provisioner key
list List provisioner keys in an organization
———
Run `coder --help` for a list of global options.
@@ -0,0 +1,16 @@
coder v0.0.0-devel
USAGE:
coder provisioner keys create [flags] <name>
Create a new provisioner key
OPTIONS:
-O, --org string, $CODER_ORGANIZATION
Select which organization (uuid or name) to use.
-t, --tag string-array, $CODER_PROVISIONERD_TAGS
Tags to filter provisioner jobs by.
———
Run `coder --help` for a list of global options.
@@ -0,0 +1,18 @@
coder v0.0.0-devel
USAGE:
coder provisioner keys delete [flags] <name>
Delete a provisioner key
Aliases: rm
OPTIONS:
-O, --org string, $CODER_ORGANIZATION
Select which organization (uuid or name) to use.
-y, --yes bool
Bypass prompts.
———
Run `coder --help` for a list of global options.
@@ -0,0 +1,15 @@
coder v0.0.0-devel
USAGE:
coder provisioner keys list [flags]
List provisioner keys in an organization
Aliases: ls
OPTIONS:
-O, --org string, $CODER_ORGANIZATION
Select which organization (uuid or name) to use.
———
Run `coder --help` for a list of global options.
@@ -0,0 +1,58 @@
coder v0.0.0-devel
USAGE:
coder provisioner start [flags]
Run a provisioner daemon
OPTIONS:
-O, --org string, $CODER_ORGANIZATION
Select which organization (uuid or name) to use.
-c, --cache-dir string, $CODER_CACHE_DIRECTORY (default: [cache dir])
Directory to store cached data.
--key string, $CODER_PROVISIONER_DAEMON_KEY
Provisioner key to authenticate with Coder server.
--log-filter string-array, $CODER_PROVISIONER_DAEMON_LOG_FILTER
Filter debug logs by matching against a given regex. Use .* to match
all debug logs.
--log-human string, $CODER_PROVISIONER_DAEMON_LOGGING_HUMAN (default: /dev/stderr)
Output human-readable logs to a given file.
--log-json string, $CODER_PROVISIONER_DAEMON_LOGGING_JSON
Output JSON logs to a given file.
--log-stackdriver string, $CODER_PROVISIONER_DAEMON_LOGGING_STACKDRIVER
Output Stackdriver compatible logs to a given file.
--name string, $CODER_PROVISIONER_DAEMON_NAME
Name of this provisioner daemon. Defaults to the current hostname
without FQDN.
--poll-interval duration, $CODER_PROVISIONERD_POLL_INTERVAL (default: 1s)
Deprecated and ignored.
--poll-jitter duration, $CODER_PROVISIONERD_POLL_JITTER (default: 100ms)
Deprecated and ignored.
--prometheus-address string, $CODER_PROMETHEUS_ADDRESS (default: 127.0.0.1:2112)
The bind address to serve prometheus metrics.
--prometheus-enable bool, $CODER_PROMETHEUS_ENABLE (default: false)
Serve prometheus metrics on the address defined by prometheus address.
--psk string, $CODER_PROVISIONER_DAEMON_PSK
Pre-shared key to authenticate with Coder server.
DEPRECATED: Use --key instead.
-t, --tag string-array, $CODER_PROVISIONERD_TAGS
Tags to filter provisioner jobs by.
--verbose bool, $CODER_PROVISIONER_DAEMON_VERBOSE (default: false)
Output debug-level logs.
———
Run `coder --help` for a list of global options.
+1 -1
View File
@@ -204,7 +204,7 @@ func convertProvisionerKeys(dbKeys []database.ProvisionerKey) []codersdk.Provisi
CreatedAt: dbKey.CreatedAt,
OrganizationID: dbKey.OrganizationID,
Name: dbKey.Name,
Tags: dbKey.Tags,
Tags: codersdk.ProvisionerKeyTags(dbKey.Tags),
// HashedSecret - never include the access token in the API response
})
}
+4 -1
View File
@@ -1060,7 +1060,7 @@ export interface ProvisionerKey {
readonly created_at: string;
readonly organization: string;
readonly name: string;
readonly tags: Record<string, string>;
readonly tags: ProvisionerKeyTags;
}
// From codersdk/provisionerdaemons.go
@@ -1069,6 +1069,9 @@ export interface ProvisionerKeyDaemons {
readonly daemons: Readonly<Array<ProvisionerDaemon>>;
}
// From codersdk/provisionerdaemons.go
export type ProvisionerKeyTags = Record<string, string>
// From codersdk/workspaces.go
export interface ProvisionerTiming {
readonly job_id: string;