mirror of https://github.com/coder/coder.git
test: add golden files to enterprise cli (#7924)
* test: Add golden files to enterprise cli
This commit is contained in:
parent
4f9d3155c9
commit
065206345e
6
Makefile
6
Makefile
|
@ -525,13 +525,17 @@ coderd/apidoc/swagger.json: $(shell find ./scripts/apidocgen $(FIND_EXCLUSIONS)
|
|||
./scripts/apidocgen/generate.sh
|
||||
yarn run --cwd=site format:write:only ../docs/api ../docs/manifest.json ../coderd/apidoc/swagger.json
|
||||
|
||||
update-golden-files: cli/testdata/.gen-golden helm/tests/testdata/.gen-golden scripts/ci-report/testdata/.gen-golden
|
||||
update-golden-files: cli/testdata/.gen-golden helm/tests/testdata/.gen-golden scripts/ci-report/testdata/.gen-golden enterprise/cli/testdata/.gen-golden
|
||||
.PHONY: update-golden-files
|
||||
|
||||
cli/testdata/.gen-golden: $(wildcard cli/testdata/*.golden) $(wildcard cli/*.tpl) $(GO_SRC_FILES)
|
||||
go test ./cli -run="Test(CommandHelp|ServerYAML)" -update
|
||||
touch "$@"
|
||||
|
||||
enterprise/cli/testdata/.gen-golden: $(wildcard enterprise/cli/testdata/*.golden) $(wildcard cli/*.tpl) $(GO_SRC_FILES)
|
||||
go test ./enterprise/cli -run="TestEnterpriseCommandHelp" -update
|
||||
touch "$@"
|
||||
|
||||
helm/tests/testdata/.gen-golden: $(wildcard helm/tests/testdata/*.yaml) $(wildcard helm/tests/testdata/*.golden) $(GO_SRC_FILES)
|
||||
go test ./helm/tests -run=TestUpdateGoldenFiles -update
|
||||
touch "$@"
|
||||
|
|
|
@ -0,0 +1,222 @@
|
|||
package clitest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/muesli/termenv"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/cli/clibase"
|
||||
"github.com/coder/coder/cli/config"
|
||||
"github.com/coder/coder/coderd/coderdtest"
|
||||
"github.com/coder/coder/coderd/database/dbtestutil"
|
||||
"github.com/coder/coder/codersdk"
|
||||
"github.com/coder/coder/testutil"
|
||||
)
|
||||
|
||||
// UpdateGoldenFiles indicates golden files should be updated.
|
||||
// To update the golden files:
|
||||
// make update-golden-files
|
||||
var UpdateGoldenFiles = flag.Bool("update", false, "update .golden files")
|
||||
|
||||
var timestampRegex = regexp.MustCompile(`(?i)\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(.\d+)?Z`)
|
||||
|
||||
type CommandHelpCase struct {
|
||||
Name string
|
||||
Cmd []string
|
||||
}
|
||||
|
||||
func DefaultCases() []CommandHelpCase {
|
||||
return []CommandHelpCase{
|
||||
{
|
||||
Name: "coder --help",
|
||||
Cmd: []string{"--help"},
|
||||
},
|
||||
{
|
||||
Name: "coder server --help",
|
||||
Cmd: []string{"server", "--help"},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// TestCommandHelp will test the help output of the given commands
|
||||
// using golden files.
|
||||
//
|
||||
//nolint:tparallel,paralleltest
|
||||
func TestCommandHelp(t *testing.T, getRoot func(t *testing.T) *clibase.Cmd, cases []CommandHelpCase) {
|
||||
ogColorProfile := lipgloss.ColorProfile()
|
||||
// ANSI256 escape codes are far easier for humans to parse in a diff,
|
||||
// but TrueColor is probably more popular with modern terminals.
|
||||
lipgloss.SetColorProfile(termenv.ANSI)
|
||||
t.Cleanup(func() {
|
||||
lipgloss.SetColorProfile(ogColorProfile)
|
||||
})
|
||||
rootClient, replacements := prepareTestData(t)
|
||||
|
||||
root := getRoot(t)
|
||||
|
||||
ExtractCommandPathsLoop:
|
||||
for _, cp := range extractVisibleCommandPaths(nil, root.Children) {
|
||||
name := fmt.Sprintf("coder %s --help", strings.Join(cp, " "))
|
||||
cmd := append(cp, "--help")
|
||||
for _, tt := range cases {
|
||||
if tt.Name == name {
|
||||
continue ExtractCommandPathsLoop
|
||||
}
|
||||
}
|
||||
cases = append(cases, CommandHelpCase{Name: name, Cmd: cmd})
|
||||
}
|
||||
|
||||
for _, tt := range cases {
|
||||
tt := tt
|
||||
t.Run(tt.Name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
|
||||
var outBuf bytes.Buffer
|
||||
|
||||
caseCmd := getRoot(t)
|
||||
|
||||
inv, cfg := NewWithCommand(t, caseCmd, tt.Cmd...)
|
||||
inv.Stderr = &outBuf
|
||||
inv.Stdout = &outBuf
|
||||
inv.Environ.Set("CODER_URL", rootClient.URL.String())
|
||||
inv.Environ.Set("CODER_SESSION_TOKEN", rootClient.SessionToken())
|
||||
inv.Environ.Set("CODER_CACHE_DIRECTORY", "~/.cache")
|
||||
|
||||
SetupConfig(t, rootClient, cfg)
|
||||
|
||||
StartWithWaiter(t, inv.WithContext(ctx)).RequireSuccess()
|
||||
|
||||
actual := outBuf.Bytes()
|
||||
if len(actual) == 0 {
|
||||
t.Fatal("no output")
|
||||
}
|
||||
|
||||
for k, v := range replacements {
|
||||
actual = bytes.ReplaceAll(actual, []byte(k), []byte(v))
|
||||
}
|
||||
|
||||
actual = NormalizeGoldenFile(t, actual)
|
||||
goldenPath := filepath.Join("testdata", strings.Replace(tt.Name, " ", "_", -1)+".golden")
|
||||
if *UpdateGoldenFiles {
|
||||
t.Logf("update golden file for: %q: %s", tt.Name, goldenPath)
|
||||
err := os.WriteFile(goldenPath, actual, 0o600)
|
||||
require.NoError(t, err, "update golden file")
|
||||
}
|
||||
|
||||
expected, err := os.ReadFile(goldenPath)
|
||||
require.NoError(t, err, "read golden file, run \"make update-golden-files\" and commit the changes")
|
||||
|
||||
expected = NormalizeGoldenFile(t, expected)
|
||||
require.Equal(
|
||||
t, string(expected), string(actual),
|
||||
"golden file mismatch: %s, run \"make update-golden-files\", verify and commit the changes",
|
||||
goldenPath,
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// NormalizeGoldenFile replaces any strings that are system or timing dependent
|
||||
// with a placeholder so that the golden files can be compared with a simple
|
||||
// equality check.
|
||||
func NormalizeGoldenFile(t *testing.T, byt []byte) []byte {
|
||||
// Replace any timestamps with a placeholder.
|
||||
byt = timestampRegex.ReplaceAll(byt, []byte("[timestamp]"))
|
||||
|
||||
homeDir, err := os.UserHomeDir()
|
||||
require.NoError(t, err)
|
||||
|
||||
configDir := config.DefaultDir()
|
||||
byt = bytes.ReplaceAll(byt, []byte(configDir), []byte("~/.config/coderv2"))
|
||||
|
||||
byt = bytes.ReplaceAll(byt, []byte(codersdk.DefaultCacheDir()), []byte("[cache dir]"))
|
||||
|
||||
// The home directory changes depending on the test environment.
|
||||
byt = bytes.ReplaceAll(byt, []byte(homeDir), []byte("~"))
|
||||
for _, r := range []struct {
|
||||
old string
|
||||
new string
|
||||
}{
|
||||
{"\r\n", "\n"},
|
||||
{`~\.cache\coder`, "~/.cache/coder"},
|
||||
{`C:\Users\RUNNER~1\AppData\Local\Temp`, "/tmp"},
|
||||
{os.TempDir(), "/tmp"},
|
||||
} {
|
||||
byt = bytes.ReplaceAll(byt, []byte(r.old), []byte(r.new))
|
||||
}
|
||||
return byt
|
||||
}
|
||||
|
||||
func extractVisibleCommandPaths(cmdPath []string, cmds []*clibase.Cmd) [][]string {
|
||||
var cmdPaths [][]string
|
||||
for _, c := range cmds {
|
||||
if c.Hidden {
|
||||
continue
|
||||
}
|
||||
cmdPath := append(cmdPath, c.Name())
|
||||
cmdPaths = append(cmdPaths, cmdPath)
|
||||
cmdPaths = append(cmdPaths, extractVisibleCommandPaths(cmdPath, c.Children)...)
|
||||
}
|
||||
return cmdPaths
|
||||
}
|
||||
|
||||
func prepareTestData(t *testing.T) (*codersdk.Client, map[string]string) {
|
||||
t.Helper()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
db, pubsub := dbtestutil.NewDB(t)
|
||||
rootClient := coderdtest.New(t, &coderdtest.Options{
|
||||
Database: db,
|
||||
Pubsub: pubsub,
|
||||
IncludeProvisionerDaemon: true,
|
||||
})
|
||||
firstUser := coderdtest.CreateFirstUser(t, rootClient)
|
||||
secondUser, err := rootClient.CreateUser(ctx, codersdk.CreateUserRequest{
|
||||
Email: "testuser2@coder.com",
|
||||
Username: "testuser2",
|
||||
Password: coderdtest.FirstUserParams.Password,
|
||||
OrganizationID: firstUser.OrganizationID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
version := coderdtest.CreateTemplateVersion(t, rootClient, firstUser.OrganizationID, nil)
|
||||
version = coderdtest.AwaitTemplateVersionJob(t, rootClient, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, rootClient, firstUser.OrganizationID, version.ID, func(req *codersdk.CreateTemplateRequest) {
|
||||
req.Name = "test-template"
|
||||
})
|
||||
workspace := coderdtest.CreateWorkspace(t, rootClient, firstUser.OrganizationID, template.ID, func(req *codersdk.CreateWorkspaceRequest) {
|
||||
req.Name = "test-workspace"
|
||||
})
|
||||
workspaceBuild := coderdtest.AwaitWorkspaceBuildJob(t, rootClient, workspace.LatestBuild.ID)
|
||||
|
||||
replacements := map[string]string{
|
||||
firstUser.UserID.String(): "[first user ID]",
|
||||
secondUser.ID.String(): "[second user ID]",
|
||||
firstUser.OrganizationID.String(): "[first org ID]",
|
||||
version.ID.String(): "[version ID]",
|
||||
version.Name: "[version name]",
|
||||
version.Job.ID.String(): "[version job ID]",
|
||||
version.Job.FileID.String(): "[version file ID]",
|
||||
version.Job.WorkerID.String(): "[version worker ID]",
|
||||
template.ID.String(): "[template ID]",
|
||||
workspace.ID.String(): "[workspace ID]",
|
||||
workspaceBuild.ID.String(): "[workspace build ID]",
|
||||
workspaceBuild.Job.ID.String(): "[workspace build job ID]",
|
||||
workspaceBuild.Job.FileID.String(): "[workspace build file ID]",
|
||||
workspaceBuild.Job.WorkerID.String(): "[workspace build worker ID]",
|
||||
}
|
||||
|
||||
return rootClient, replacements
|
||||
}
|
232
cli/root_test.go
232
cli/root_test.go
|
@ -2,235 +2,47 @@ package cli_test
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/muesli/termenv"
|
||||
"github.com/coder/coder/cli/clibase"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/buildinfo"
|
||||
"github.com/coder/coder/cli"
|
||||
"github.com/coder/coder/cli/clibase"
|
||||
"github.com/coder/coder/cli/clitest"
|
||||
"github.com/coder/coder/cli/config"
|
||||
"github.com/coder/coder/coderd/coderdtest"
|
||||
"github.com/coder/coder/coderd/database/dbtestutil"
|
||||
"github.com/coder/coder/codersdk"
|
||||
"github.com/coder/coder/testutil"
|
||||
)
|
||||
|
||||
// To update the golden files:
|
||||
// make update-golden-files
|
||||
var updateGoldenFiles = flag.Bool("update", false, "update .golden files")
|
||||
|
||||
var timestampRegex = regexp.MustCompile(`(?i)\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(.\d+)?Z`)
|
||||
|
||||
// We need to override the global color profile.
|
||||
//
|
||||
//nolint:tparallel,paralleltest
|
||||
func TestCommandHelp(t *testing.T) {
|
||||
ogColorProfile := lipgloss.ColorProfile()
|
||||
// ANSI256 escape codes are far easier for humans to parse in a diff,
|
||||
// but TrueColor is probably more popular with modern terminals.
|
||||
lipgloss.SetColorProfile(termenv.ANSI)
|
||||
t.Cleanup(func() {
|
||||
lipgloss.SetColorProfile(ogColorProfile)
|
||||
})
|
||||
rootClient, replacements := prepareTestData(t)
|
||||
// Test with AGPL commands
|
||||
getCmds := func(t *testing.T) *clibase.Cmd {
|
||||
// Must return a fresh instance of cmds each time.
|
||||
|
||||
type testCase struct {
|
||||
name string
|
||||
cmd []string
|
||||
t.Helper()
|
||||
var root cli.RootCmd
|
||||
rootCmd, err := root.Command(root.AGPL())
|
||||
require.NoError(t, err)
|
||||
|
||||
return rootCmd
|
||||
}
|
||||
tests := []testCase{
|
||||
{
|
||||
name: "coder --help",
|
||||
cmd: []string{"--help"},
|
||||
clitest.TestCommandHelp(t, getCmds, append(clitest.DefaultCases(),
|
||||
clitest.CommandHelpCase{
|
||||
Name: "coder agent --help",
|
||||
Cmd: []string{"agent", "--help"},
|
||||
},
|
||||
{
|
||||
name: "coder server --help",
|
||||
cmd: []string{"server", "--help"},
|
||||
clitest.CommandHelpCase{
|
||||
Name: "coder list --output json",
|
||||
Cmd: []string{"list", "--output", "json"},
|
||||
},
|
||||
{
|
||||
name: "coder agent --help",
|
||||
cmd: []string{"agent", "--help"},
|
||||
clitest.CommandHelpCase{
|
||||
Name: "coder users list --output json",
|
||||
Cmd: []string{"users", "list", "--output", "json"},
|
||||
},
|
||||
{
|
||||
name: "coder list --output json",
|
||||
cmd: []string{"list", "--output", "json"},
|
||||
},
|
||||
{
|
||||
name: "coder users list --output json",
|
||||
cmd: []string{"users", "list", "--output", "json"},
|
||||
},
|
||||
}
|
||||
|
||||
rootCmd := new(cli.RootCmd)
|
||||
root, err := rootCmd.Command(rootCmd.AGPL())
|
||||
require.NoError(t, err)
|
||||
|
||||
ExtractCommandPathsLoop:
|
||||
for _, cp := range extractVisibleCommandPaths(nil, root.Children) {
|
||||
name := fmt.Sprintf("coder %s --help", strings.Join(cp, " "))
|
||||
cmd := append(cp, "--help")
|
||||
for _, tt := range tests {
|
||||
if tt.name == name {
|
||||
continue ExtractCommandPathsLoop
|
||||
}
|
||||
}
|
||||
tests = append(tests, testCase{name: name, cmd: cmd})
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
|
||||
var outBuf bytes.Buffer
|
||||
inv, cfg := clitest.New(t, tt.cmd...)
|
||||
inv.Stderr = &outBuf
|
||||
inv.Stdout = &outBuf
|
||||
inv.Environ.Set("CODER_URL", rootClient.URL.String())
|
||||
inv.Environ.Set("CODER_SESSION_TOKEN", rootClient.SessionToken())
|
||||
inv.Environ.Set("CODER_CACHE_DIRECTORY", "~/.cache")
|
||||
|
||||
clitest.SetupConfig(t, rootClient, cfg)
|
||||
|
||||
clitest.StartWithWaiter(t, inv.WithContext(ctx)).RequireSuccess()
|
||||
|
||||
actual := outBuf.Bytes()
|
||||
if len(actual) == 0 {
|
||||
t.Fatal("no output")
|
||||
}
|
||||
|
||||
for k, v := range replacements {
|
||||
actual = bytes.ReplaceAll(actual, []byte(k), []byte(v))
|
||||
}
|
||||
|
||||
actual = normalizeGoldenFile(t, actual)
|
||||
goldenPath := filepath.Join("testdata", strings.Replace(tt.name, " ", "_", -1)+".golden")
|
||||
if *updateGoldenFiles {
|
||||
t.Logf("update golden file for: %q: %s", tt.name, goldenPath)
|
||||
err = os.WriteFile(goldenPath, actual, 0o600)
|
||||
require.NoError(t, err, "update golden file")
|
||||
}
|
||||
|
||||
expected, err := os.ReadFile(goldenPath)
|
||||
require.NoError(t, err, "read golden file, run \"make update-golden-files\" and commit the changes")
|
||||
|
||||
expected = normalizeGoldenFile(t, expected)
|
||||
require.Equal(
|
||||
t, string(expected), string(actual),
|
||||
"golden file mismatch: %s, run \"make update-golden-files\", verify and commit the changes",
|
||||
goldenPath,
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// normalizeGoldenFiles replaces any strings that are system or timing dependent
|
||||
// with a placeholder so that the golden files can be compared with a simple
|
||||
// equality check.
|
||||
func normalizeGoldenFile(t *testing.T, byt []byte) []byte {
|
||||
// Replace any timestamps with a placeholder.
|
||||
byt = timestampRegex.ReplaceAll(byt, []byte("[timestamp]"))
|
||||
|
||||
homeDir, err := os.UserHomeDir()
|
||||
require.NoError(t, err)
|
||||
|
||||
configDir := config.DefaultDir()
|
||||
byt = bytes.ReplaceAll(byt, []byte(configDir), []byte("~/.config/coderv2"))
|
||||
|
||||
byt = bytes.ReplaceAll(byt, []byte(codersdk.DefaultCacheDir()), []byte("[cache dir]"))
|
||||
|
||||
// The home directory changes depending on the test environment.
|
||||
byt = bytes.ReplaceAll(byt, []byte(homeDir), []byte("~"))
|
||||
for _, r := range []struct {
|
||||
old string
|
||||
new string
|
||||
}{
|
||||
{"\r\n", "\n"},
|
||||
{`~\.cache\coder`, "~/.cache/coder"},
|
||||
{`C:\Users\RUNNER~1\AppData\Local\Temp`, "/tmp"},
|
||||
{os.TempDir(), "/tmp"},
|
||||
} {
|
||||
byt = bytes.ReplaceAll(byt, []byte(r.old), []byte(r.new))
|
||||
}
|
||||
return byt
|
||||
}
|
||||
|
||||
func extractVisibleCommandPaths(cmdPath []string, cmds []*clibase.Cmd) [][]string {
|
||||
var cmdPaths [][]string
|
||||
for _, c := range cmds {
|
||||
if c.Hidden {
|
||||
continue
|
||||
}
|
||||
cmdPath := append(cmdPath, c.Name())
|
||||
cmdPaths = append(cmdPaths, cmdPath)
|
||||
cmdPaths = append(cmdPaths, extractVisibleCommandPaths(cmdPath, c.Children)...)
|
||||
}
|
||||
return cmdPaths
|
||||
}
|
||||
|
||||
func prepareTestData(t *testing.T) (*codersdk.Client, map[string]string) {
|
||||
t.Helper()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
db, pubsub := dbtestutil.NewDB(t)
|
||||
rootClient := coderdtest.New(t, &coderdtest.Options{
|
||||
Database: db,
|
||||
Pubsub: pubsub,
|
||||
IncludeProvisionerDaemon: true,
|
||||
})
|
||||
firstUser := coderdtest.CreateFirstUser(t, rootClient)
|
||||
secondUser, err := rootClient.CreateUser(ctx, codersdk.CreateUserRequest{
|
||||
Email: "testuser2@coder.com",
|
||||
Username: "testuser2",
|
||||
Password: coderdtest.FirstUserParams.Password,
|
||||
OrganizationID: firstUser.OrganizationID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
version := coderdtest.CreateTemplateVersion(t, rootClient, firstUser.OrganizationID, nil)
|
||||
version = coderdtest.AwaitTemplateVersionJob(t, rootClient, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, rootClient, firstUser.OrganizationID, version.ID, func(req *codersdk.CreateTemplateRequest) {
|
||||
req.Name = "test-template"
|
||||
})
|
||||
workspace := coderdtest.CreateWorkspace(t, rootClient, firstUser.OrganizationID, template.ID, func(req *codersdk.CreateWorkspaceRequest) {
|
||||
req.Name = "test-workspace"
|
||||
})
|
||||
workspaceBuild := coderdtest.AwaitWorkspaceBuildJob(t, rootClient, workspace.LatestBuild.ID)
|
||||
|
||||
replacements := map[string]string{
|
||||
firstUser.UserID.String(): "[first user ID]",
|
||||
secondUser.ID.String(): "[second user ID]",
|
||||
firstUser.OrganizationID.String(): "[first org ID]",
|
||||
version.ID.String(): "[version ID]",
|
||||
version.Name: "[version name]",
|
||||
version.Job.ID.String(): "[version job ID]",
|
||||
version.Job.FileID.String(): "[version file ID]",
|
||||
version.Job.WorkerID.String(): "[version worker ID]",
|
||||
template.ID.String(): "[template ID]",
|
||||
workspace.ID.String(): "[workspace ID]",
|
||||
workspaceBuild.ID.String(): "[workspace build ID]",
|
||||
workspaceBuild.Job.ID.String(): "[workspace build job ID]",
|
||||
workspaceBuild.Job.FileID.String(): "[workspace build file ID]",
|
||||
workspaceBuild.Job.WorkerID.String(): "[workspace build worker ID]",
|
||||
}
|
||||
|
||||
return rootClient, replacements
|
||||
))
|
||||
}
|
||||
|
||||
func TestRoot(t *testing.T) {
|
||||
|
|
|
@ -1607,15 +1607,15 @@ func TestServerYAMLConfig(t *testing.T) {
|
|||
|
||||
goldenPath := filepath.Join("testdata", "server-config.yaml.golden")
|
||||
|
||||
wantByt = normalizeGoldenFile(t, wantByt)
|
||||
if *updateGoldenFiles {
|
||||
wantByt = clitest.NormalizeGoldenFile(t, wantByt)
|
||||
if *clitest.UpdateGoldenFiles {
|
||||
require.NoError(t, os.WriteFile(goldenPath, wantByt, 0o600))
|
||||
return
|
||||
}
|
||||
|
||||
got, err := os.ReadFile(goldenPath)
|
||||
require.NoError(t, err)
|
||||
got = normalizeGoldenFile(t, got)
|
||||
got = clitest.NormalizeGoldenFile(t, got)
|
||||
|
||||
require.Equal(t, string(wantByt), string(got))
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/coder/coder/cli"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/cli/clibase"
|
||||
|
||||
"github.com/coder/coder/cli/clitest"
|
||||
)
|
||||
|
||||
//nolint:tparallel,paralleltest
|
||||
func TestEnterpriseCommandHelp(t *testing.T) {
|
||||
// Only test the enterprise commands
|
||||
getCmds := func(t *testing.T) *clibase.Cmd {
|
||||
// Must return a fresh instance of cmds each time.
|
||||
t.Helper()
|
||||
var root cli.RootCmd
|
||||
rootCmd, err := root.Command((&RootCmd{}).enterpriseOnly())
|
||||
require.NoError(t, err)
|
||||
|
||||
return rootCmd
|
||||
}
|
||||
clitest.TestCommandHelp(t, getCmds, clitest.DefaultCases())
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
Usage: coder [global-flags] <subcommand>
|
||||
|
||||
Coder v0.0.0-devel — A tool for provisioning self-hosted development environments with Terraform.
|
||||
- Start a Coder server:
|
||||
|
||||
[40m [0m[91;40m$ coder server[0m[40m [0m
|
||||
|
||||
- Get started by creating a template from an example:
|
||||
|
||||
[40m [0m[91;40m$ coder templates init[0m[40m [0m
|
||||
|
||||
[1mSubcommands[0m
|
||||
features List Enterprise features
|
||||
groups Manage groups
|
||||
licenses Add, delete, and list licenses
|
||||
provisionerd Manage provisioner daemons
|
||||
server Start a Coder server
|
||||
|
||||
[1mGlobal Options[0m
|
||||
Global options are applied to all commands. They can be set using environment
|
||||
variables or flags.
|
||||
|
||||
--debug-options bool
|
||||
Print all options, how they're set, then exit.
|
||||
|
||||
--global-config string, $CODER_CONFIG_DIR (default: ~/.config/coderv2)
|
||||
Path to the global `coder` config directory.
|
||||
|
||||
--header string-array, $CODER_HEADER
|
||||
Additional HTTP headers added to all requests. Provide as key=value.
|
||||
Can be specified multiple times.
|
||||
|
||||
--no-feature-warning bool, $CODER_NO_FEATURE_WARNING
|
||||
Suppress warnings about unlicensed features.
|
||||
|
||||
--no-version-warning bool, $CODER_NO_VERSION_WARNING
|
||||
Suppress warning when client and server versions do not match.
|
||||
|
||||
--token string, $CODER_SESSION_TOKEN
|
||||
Specify an authentication token. For security reasons setting
|
||||
CODER_SESSION_TOKEN is preferred.
|
||||
|
||||
--url url, $CODER_URL
|
||||
URL to a deployment.
|
||||
|
||||
-v, --verbose bool, $CODER_VERBOSE
|
||||
Enable verbose output.
|
||||
|
||||
---
|
||||
Report bugs and request features at https://github.com/coder/coder/issues/new
|
|
@ -0,0 +1,11 @@
|
|||
Usage: coder features
|
||||
|
||||
List Enterprise features
|
||||
|
||||
Aliases: feature
|
||||
|
||||
[1mSubcommands[0m
|
||||
list
|
||||
|
||||
---
|
||||
Run `coder --help` for a list of global options.
|
|
@ -0,0 +1,14 @@
|
|||
Usage: coder features list [flags]
|
||||
|
||||
Aliases: ls
|
||||
|
||||
[1mOptions[0m
|
||||
-c, --column string-array (default: Name,Entitlement,Enabled,Limit,Actual)
|
||||
Specify a column to filter in the table. Available columns are: Name,
|
||||
Entitlement, Enabled, Limit, Actual.
|
||||
|
||||
-o, --output string (default: table)
|
||||
Output format. Available formats are: table, json.
|
||||
|
||||
---
|
||||
Run `coder --help` for a list of global options.
|
|
@ -0,0 +1,14 @@
|
|||
Usage: coder groups
|
||||
|
||||
Manage groups
|
||||
|
||||
Aliases: group
|
||||
|
||||
[1mSubcommands[0m
|
||||
create Create a user group
|
||||
delete Delete a user group
|
||||
edit Edit a user group
|
||||
list List user groups
|
||||
|
||||
---
|
||||
Run `coder --help` for a list of global options.
|
|
@ -0,0 +1,10 @@
|
|||
Usage: coder groups create [flags] <name>
|
||||
|
||||
Create a user group
|
||||
|
||||
[1mOptions[0m
|
||||
-u, --avatar-url string, $CODER_AVATAR_URL
|
||||
Set an avatar for a group.
|
||||
|
||||
---
|
||||
Run `coder --help` for a list of global options.
|
|
@ -0,0 +1,8 @@
|
|||
Usage: coder groups delete <name>
|
||||
|
||||
Delete a user group
|
||||
|
||||
Aliases: rm
|
||||
|
||||
---
|
||||
Run `coder --help` for a list of global options.
|
|
@ -0,0 +1,19 @@
|
|||
Usage: coder groups edit [flags] <name>
|
||||
|
||||
Edit a user group
|
||||
|
||||
[1mOptions[0m
|
||||
-a, --add-users string-array
|
||||
Add users to the group. Accepts emails or IDs.
|
||||
|
||||
-u, --avatar-url string
|
||||
Update the group avatar.
|
||||
|
||||
-n, --name string
|
||||
Update the group name.
|
||||
|
||||
-r, --rm-users string-array
|
||||
Remove users to the group. Accepts emails or IDs.
|
||||
|
||||
---
|
||||
Run `coder --help` for a list of global options.
|
|
@ -0,0 +1,14 @@
|
|||
Usage: coder groups list [flags]
|
||||
|
||||
List user groups
|
||||
|
||||
[1mOptions[0m
|
||||
-c, --column string-array (default: name,organization id,members,avatar url)
|
||||
Columns to display in table output. Available columns: name,
|
||||
organization id, members, avatar url.
|
||||
|
||||
-o, --output string (default: table)
|
||||
Output format. Available formats: table, json.
|
||||
|
||||
---
|
||||
Run `coder --help` for a list of global options.
|
|
@ -0,0 +1,13 @@
|
|||
Usage: coder licenses
|
||||
|
||||
Add, delete, and list licenses
|
||||
|
||||
Aliases: license
|
||||
|
||||
[1mSubcommands[0m
|
||||
add Add license to Coder deployment
|
||||
delete Delete license by ID
|
||||
list List licenses (including expired)
|
||||
|
||||
---
|
||||
Run `coder --help` for a list of global options.
|
|
@ -0,0 +1,16 @@
|
|||
Usage: coder licenses add [flags] [-f file | -l license]
|
||||
|
||||
Add license to Coder deployment
|
||||
|
||||
[1mOptions[0m
|
||||
--debug bool
|
||||
Output license claims for debugging.
|
||||
|
||||
-f, --file string
|
||||
Load license from file.
|
||||
|
||||
-l, --license string
|
||||
License string.
|
||||
|
||||
---
|
||||
Run `coder --help` for a list of global options.
|
|
@ -0,0 +1,8 @@
|
|||
Usage: coder licenses delete <id>
|
||||
|
||||
Delete license by ID
|
||||
|
||||
Aliases: del, rm
|
||||
|
||||
---
|
||||
Run `coder --help` for a list of global options.
|
|
@ -0,0 +1,8 @@
|
|||
Usage: coder licenses list
|
||||
|
||||
List licenses (including expired)
|
||||
|
||||
Aliases: ls
|
||||
|
||||
---
|
||||
Run `coder --help` for a list of global options.
|
|
@ -0,0 +1,9 @@
|
|||
Usage: coder provisionerd
|
||||
|
||||
Manage provisioner daemons
|
||||
|
||||
[1mSubcommands[0m
|
||||
start Run a provisioner daemon
|
||||
|
||||
---
|
||||
Run `coder --help` for a list of global options.
|
|
@ -0,0 +1,19 @@
|
|||
Usage: coder provisionerd start [flags]
|
||||
|
||||
Run a provisioner daemon
|
||||
|
||||
[1mOptions[0m
|
||||
-c, --cache-dir string, $CODER_CACHE_DIRECTORY (default: [cache dir])
|
||||
Directory to store cached data.
|
||||
|
||||
--poll-interval duration, $CODER_PROVISIONERD_POLL_INTERVAL (default: 1s)
|
||||
How often to poll for provisioner jobs.
|
||||
|
||||
--poll-jitter duration, $CODER_PROVISIONERD_POLL_JITTER (default: 100ms)
|
||||
How much to jitter the poll interval by.
|
||||
|
||||
-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,395 @@
|
|||
Usage: coder server [flags]
|
||||
|
||||
Start a Coder server
|
||||
|
||||
[1mSubcommands[0m
|
||||
create-admin-user Create a new admin user with the given username,
|
||||
email and password and adds it to every
|
||||
organization.
|
||||
postgres-builtin-serve Run the built-in PostgreSQL deployment.
|
||||
postgres-builtin-url Output the connection URL for the built-in
|
||||
PostgreSQL deployment.
|
||||
|
||||
[1mOptions[0m
|
||||
--cache-dir string, $CODER_CACHE_DIRECTORY (default: [cache dir])
|
||||
The directory to cache temporary files. If unspecified and
|
||||
$CACHE_DIRECTORY is set, it will be used for compatibility with
|
||||
systemd.
|
||||
|
||||
--disable-owner-workspace-access bool, $CODER_DISABLE_OWNER_WORKSPACE_ACCESS
|
||||
Remove the permission for the 'owner' role to have workspace execution
|
||||
on all workspaces. This prevents the 'owner' from ssh, apps, and
|
||||
terminal access based on the 'owner' role. They still have their user
|
||||
permissions to access their own workspaces.
|
||||
|
||||
--disable-path-apps bool, $CODER_DISABLE_PATH_APPS
|
||||
Disable workspace apps that are not served from subdomains. Path-based
|
||||
apps can make requests to the Coder API and pose a security risk when
|
||||
the workspace serves malicious JavaScript. This is recommended for
|
||||
security purposes if a --wildcard-access-url is configured.
|
||||
|
||||
--swagger-enable bool, $CODER_SWAGGER_ENABLE
|
||||
Expose the swagger endpoint via /swagger.
|
||||
|
||||
--experiments string-array, $CODER_EXPERIMENTS
|
||||
Enable one or more experiments. These are not ready for production.
|
||||
Separate multiple experiments with commas, or enter '*' to opt-in to
|
||||
all available experiments.
|
||||
|
||||
--postgres-url string, $CODER_PG_CONNECTION_URL
|
||||
URL of a PostgreSQL database. If empty, PostgreSQL binaries will be
|
||||
downloaded from Maven (https://repo1.maven.org/maven2) and store all
|
||||
data in the config root. Access the built-in database with "coder
|
||||
server postgres-builtin-url".
|
||||
|
||||
--ssh-keygen-algorithm string, $CODER_SSH_KEYGEN_ALGORITHM (default: ed25519)
|
||||
The algorithm to use for generating ssh keys. Accepted values are
|
||||
"ed25519", "ecdsa", or "rsa4096".
|
||||
|
||||
--update-check bool, $CODER_UPDATE_CHECK (default: false)
|
||||
Periodically check for new releases of Coder and inform the owner. The
|
||||
check is performed once per day.
|
||||
|
||||
[1mClient Options[0m
|
||||
These options change the behavior of how clients interact with the Coder.
|
||||
Clients include the coder cli, vs code extension, and the web UI.
|
||||
|
||||
--ssh-config-options string-array, $CODER_SSH_CONFIG_OPTIONS
|
||||
These SSH config options will override the default SSH config options.
|
||||
Provide options in "key=value" or "key value" format separated by
|
||||
commas.Using this incorrectly can break SSH to your deployment, use
|
||||
cautiously.
|
||||
|
||||
--ssh-hostname-prefix string, $CODER_SSH_HOSTNAME_PREFIX (default: coder.)
|
||||
The SSH deployment prefix is used in the Host of the ssh config.
|
||||
|
||||
[1mConfig Options[0m
|
||||
Use a YAML configuration file when your server launch become unwieldy.
|
||||
|
||||
-c, --config yaml-config-path, $CODER_CONFIG_PATH
|
||||
Specify a YAML file to load configuration from.
|
||||
|
||||
--write-config bool
|
||||
|
||||
Write out the current server config as YAML to stdout.
|
||||
|
||||
[1mIntrospection / Logging Options[0m
|
||||
--log-human string, $CODER_LOGGING_HUMAN (default: /dev/stderr)
|
||||
Output human-readable logs to a given file.
|
||||
|
||||
--log-json string, $CODER_LOGGING_JSON
|
||||
Output JSON logs to a given file.
|
||||
|
||||
--log-stackdriver string, $CODER_LOGGING_STACKDRIVER
|
||||
Output Stackdriver compatible logs to a given file.
|
||||
|
||||
-v, --verbose bool, $CODER_VERBOSE
|
||||
Output debug-level logs.
|
||||
|
||||
[1mIntrospection / Prometheus Options[0m
|
||||
--prometheus-address host:port, $CODER_PROMETHEUS_ADDRESS (default: 127.0.0.1:2112)
|
||||
The bind address to serve prometheus metrics.
|
||||
|
||||
--prometheus-collect-agent-stats bool, $CODER_PROMETHEUS_COLLECT_AGENT_STATS
|
||||
Collect agent stats (may increase charges for metrics storage).
|
||||
|
||||
--prometheus-enable bool, $CODER_PROMETHEUS_ENABLE
|
||||
Serve prometheus metrics on the address defined by prometheus address.
|
||||
|
||||
[1mIntrospection / Tracing Options[0m
|
||||
--trace-logs bool, $CODER_TRACE_LOGS
|
||||
Enables capturing of logs as events in traces. This is useful for
|
||||
debugging, but may result in a very large amount of events being sent
|
||||
to the tracing backend which may incur significant costs. If the
|
||||
verbose flag was supplied, debug-level logs will be included.
|
||||
|
||||
--trace bool, $CODER_TRACE_ENABLE
|
||||
Whether application tracing data is collected. It exports to a backend
|
||||
configured by environment variables. See:
|
||||
https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md.
|
||||
|
||||
--trace-honeycomb-api-key string, $CODER_TRACE_HONEYCOMB_API_KEY
|
||||
Enables trace exporting to Honeycomb.io using the provided API Key.
|
||||
|
||||
[1mIntrospection / pprof Options[0m
|
||||
--pprof-address host:port, $CODER_PPROF_ADDRESS (default: 127.0.0.1:6060)
|
||||
The bind address to serve pprof.
|
||||
|
||||
--pprof-enable bool, $CODER_PPROF_ENABLE
|
||||
Serve pprof metrics on the address defined by pprof address.
|
||||
|
||||
[1mNetworking Options[0m
|
||||
--access-url url, $CODER_ACCESS_URL
|
||||
The URL that users will use to access the Coder deployment.
|
||||
|
||||
--proxy-trusted-headers string-array, $CODER_PROXY_TRUSTED_HEADERS
|
||||
Headers to trust for forwarding IP addresses. e.g. Cf-Connecting-Ip,
|
||||
True-Client-Ip, X-Forwarded-For.
|
||||
|
||||
--proxy-trusted-origins string-array, $CODER_PROXY_TRUSTED_ORIGINS
|
||||
Origin addresses to respect "proxy-trusted-headers". e.g.
|
||||
192.168.1.0/24.
|
||||
|
||||
--redirect-to-access-url bool, $CODER_REDIRECT_TO_ACCESS_URL
|
||||
Specifies whether to redirect requests that do not match the access
|
||||
URL host.
|
||||
|
||||
--secure-auth-cookie bool, $CODER_SECURE_AUTH_COOKIE
|
||||
Controls if the 'Secure' property is set on browser session cookies.
|
||||
|
||||
--wildcard-access-url url, $CODER_WILDCARD_ACCESS_URL
|
||||
Specifies the wildcard hostname to use for workspace applications in
|
||||
the form "*.example.com".
|
||||
|
||||
[1mNetworking / DERP Options[0m
|
||||
Most Coder deployments never have to think about DERP because all connections
|
||||
between workspaces and users are peer-to-peer. However, when Coder cannot
|
||||
establish a peer to peer connection, Coder uses a distributed relay network
|
||||
backed by Tailscale and WireGuard.
|
||||
|
||||
--derp-config-path string, $CODER_DERP_CONFIG_PATH
|
||||
Path to read a DERP mapping from. See:
|
||||
https://tailscale.com/kb/1118/custom-derp-servers/.
|
||||
|
||||
--derp-config-url string, $CODER_DERP_CONFIG_URL
|
||||
URL to fetch a DERP mapping on startup. See:
|
||||
https://tailscale.com/kb/1118/custom-derp-servers/.
|
||||
|
||||
--derp-server-enable bool, $CODER_DERP_SERVER_ENABLE (default: true)
|
||||
Whether to enable or disable the embedded DERP relay server.
|
||||
|
||||
--derp-server-region-code string, $CODER_DERP_SERVER_REGION_CODE (default: coder)
|
||||
Region code to use for the embedded DERP server.
|
||||
|
||||
--derp-server-region-id int, $CODER_DERP_SERVER_REGION_ID (default: 999)
|
||||
Region ID to use for the embedded DERP server.
|
||||
|
||||
--derp-server-region-name string, $CODER_DERP_SERVER_REGION_NAME (default: Coder Embedded Relay)
|
||||
Region name that for the embedded DERP server.
|
||||
|
||||
--derp-server-stun-addresses string-array, $CODER_DERP_SERVER_STUN_ADDRESSES (default: stun.l.google.com:19302)
|
||||
Addresses for STUN servers to establish P2P connections. Use special
|
||||
value 'disable' to turn off STUN.
|
||||
|
||||
[1mNetworking / HTTP Options[0m
|
||||
--disable-password-auth bool, $CODER_DISABLE_PASSWORD_AUTH
|
||||
Disable password authentication. This is recommended for security
|
||||
purposes in production deployments that rely on an identity provider.
|
||||
Any user with the owner role will be able to sign in with their
|
||||
password regardless of this setting to avoid potential lock out. If
|
||||
you are locked out of your account, you can use the `coder server
|
||||
create-admin` command to create a new admin user directly in the
|
||||
database.
|
||||
|
||||
--disable-session-expiry-refresh bool, $CODER_DISABLE_SESSION_EXPIRY_REFRESH
|
||||
Disable automatic session expiry bumping due to activity. This forces
|
||||
all sessions to become invalid after the session expiry duration has
|
||||
been reached.
|
||||
|
||||
--http-address string, $CODER_HTTP_ADDRESS (default: 127.0.0.1:3000)
|
||||
HTTP bind address of the server. Unset to disable the HTTP endpoint.
|
||||
|
||||
--max-token-lifetime duration, $CODER_MAX_TOKEN_LIFETIME (default: 876600h0m0s)
|
||||
The maximum lifetime duration users can specify when creating an API
|
||||
token.
|
||||
|
||||
--proxy-health-interval duration, $CODER_PROXY_HEALTH_INTERVAL (default: 1m0s)
|
||||
The interval in which coderd should be checking the status of
|
||||
workspace proxies.
|
||||
|
||||
--session-duration duration, $CODER_SESSION_DURATION (default: 24h0m0s)
|
||||
The token expiry duration for browser sessions. Sessions may last
|
||||
longer if they are actively making requests, but this functionality
|
||||
can be disabled via --disable-session-expiry-refresh.
|
||||
|
||||
[1mNetworking / TLS Options[0m
|
||||
Configure TLS / HTTPS for your Coder deployment. If you're running Coder behind
|
||||
a TLS-terminating reverse proxy or are accessing Coder over a secure link, you
|
||||
can safely ignore these settings.
|
||||
|
||||
--strict-transport-security int, $CODER_STRICT_TRANSPORT_SECURITY (default: 0)
|
||||
Controls if the 'Strict-Transport-Security' header is set on all
|
||||
static file responses. This header should only be set if the server is
|
||||
accessed via HTTPS. This value is the MaxAge in seconds of the header.
|
||||
|
||||
--strict-transport-security-options string-array, $CODER_STRICT_TRANSPORT_SECURITY_OPTIONS
|
||||
Two optional fields can be set in the Strict-Transport-Security
|
||||
header; 'includeSubDomains' and 'preload'. The
|
||||
'strict-transport-security' flag must be set to a non-zero value for
|
||||
these options to be used.
|
||||
|
||||
--tls-address host:port, $CODER_TLS_ADDRESS (default: 127.0.0.1:3443)
|
||||
HTTPS bind address of the server.
|
||||
|
||||
--tls-cert-file string-array, $CODER_TLS_CERT_FILE
|
||||
Path to each certificate for TLS. It requires a PEM-encoded file. To
|
||||
configure the listener to use a CA certificate, concatenate the
|
||||
primary certificate and the CA certificate together. The primary
|
||||
certificate should appear first in the combined file.
|
||||
|
||||
--tls-client-auth string, $CODER_TLS_CLIENT_AUTH (default: none)
|
||||
Policy the server will follow for TLS Client Authentication. Accepted
|
||||
values are "none", "request", "require-any", "verify-if-given", or
|
||||
"require-and-verify".
|
||||
|
||||
--tls-client-ca-file string, $CODER_TLS_CLIENT_CA_FILE
|
||||
PEM-encoded Certificate Authority file used for checking the
|
||||
authenticity of client.
|
||||
|
||||
--tls-client-cert-file string, $CODER_TLS_CLIENT_CERT_FILE
|
||||
Path to certificate for client TLS authentication. It requires a
|
||||
PEM-encoded file.
|
||||
|
||||
--tls-client-key-file string, $CODER_TLS_CLIENT_KEY_FILE
|
||||
Path to key for client TLS authentication. It requires a PEM-encoded
|
||||
file.
|
||||
|
||||
--tls-enable bool, $CODER_TLS_ENABLE
|
||||
Whether TLS will be enabled.
|
||||
|
||||
--tls-key-file string-array, $CODER_TLS_KEY_FILE
|
||||
Paths to the private keys for each of the certificates. It requires a
|
||||
PEM-encoded file.
|
||||
|
||||
--tls-min-version string, $CODER_TLS_MIN_VERSION (default: tls12)
|
||||
Minimum supported version of TLS. Accepted values are "tls10",
|
||||
"tls11", "tls12" or "tls13".
|
||||
|
||||
[1mOAuth2 / GitHub Options[0m
|
||||
--oauth2-github-allow-everyone bool, $CODER_OAUTH2_GITHUB_ALLOW_EVERYONE
|
||||
Allow all logins, setting this option means allowed orgs and teams
|
||||
must be empty.
|
||||
|
||||
--oauth2-github-allow-signups bool, $CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS
|
||||
Whether new users can sign up with GitHub.
|
||||
|
||||
--oauth2-github-allowed-orgs string-array, $CODER_OAUTH2_GITHUB_ALLOWED_ORGS
|
||||
Organizations the user must be a member of to Login with GitHub.
|
||||
|
||||
--oauth2-github-allowed-teams string-array, $CODER_OAUTH2_GITHUB_ALLOWED_TEAMS
|
||||
Teams inside organizations the user must be a member of to Login with
|
||||
GitHub. Structured as: <organization-name>/<team-slug>.
|
||||
|
||||
--oauth2-github-client-id string, $CODER_OAUTH2_GITHUB_CLIENT_ID
|
||||
Client ID for Login with GitHub.
|
||||
|
||||
--oauth2-github-client-secret string, $CODER_OAUTH2_GITHUB_CLIENT_SECRET
|
||||
Client secret for Login with GitHub.
|
||||
|
||||
--oauth2-github-enterprise-base-url string, $CODER_OAUTH2_GITHUB_ENTERPRISE_BASE_URL
|
||||
Base URL of a GitHub Enterprise deployment to use for Login with
|
||||
GitHub.
|
||||
|
||||
[1mOIDC Options[0m
|
||||
--oidc-allow-signups bool, $CODER_OIDC_ALLOW_SIGNUPS (default: true)
|
||||
Whether new users can sign up with OIDC.
|
||||
|
||||
--oidc-auth-url-params struct[map[string]string], $CODER_OIDC_AUTH_URL_PARAMS (default: {"access_type": "offline"})
|
||||
OIDC auth URL parameters to pass to the upstream provider.
|
||||
|
||||
--oidc-client-id string, $CODER_OIDC_CLIENT_ID
|
||||
Client ID to use for Login with OIDC.
|
||||
|
||||
--oidc-client-secret string, $CODER_OIDC_CLIENT_SECRET
|
||||
Client secret to use for Login with OIDC.
|
||||
|
||||
--oidc-email-domain string-array, $CODER_OIDC_EMAIL_DOMAIN
|
||||
Email domains that clients logging in with OIDC must match.
|
||||
|
||||
--oidc-email-field string, $CODER_OIDC_EMAIL_FIELD (default: email)
|
||||
OIDC claim field to use as the email.
|
||||
|
||||
--oidc-group-field string, $CODER_OIDC_GROUP_FIELD
|
||||
This field must be set if using the group sync feature and the scope
|
||||
name is not 'groups'. Set to the claim to be used for groups.
|
||||
|
||||
--oidc-group-mapping struct[map[string]string], $CODER_OIDC_GROUP_MAPPING (default: {})
|
||||
A map of OIDC group IDs and the group in Coder it should map to. This
|
||||
is useful for when OIDC providers only return group IDs.
|
||||
|
||||
--oidc-ignore-email-verified bool, $CODER_OIDC_IGNORE_EMAIL_VERIFIED
|
||||
Ignore the email_verified claim from the upstream provider.
|
||||
|
||||
--oidc-ignore-userinfo bool, $CODER_OIDC_IGNORE_USERINFO (default: false)
|
||||
Ignore the userinfo endpoint and only use the ID token for user
|
||||
information.
|
||||
|
||||
--oidc-issuer-url string, $CODER_OIDC_ISSUER_URL
|
||||
Issuer URL to use for Login with OIDC.
|
||||
|
||||
--oidc-scopes string-array, $CODER_OIDC_SCOPES (default: openid,profile,email)
|
||||
Scopes to grant when authenticating with OIDC.
|
||||
|
||||
--oidc-username-field string, $CODER_OIDC_USERNAME_FIELD (default: preferred_username)
|
||||
OIDC claim field to use as the username.
|
||||
|
||||
--oidc-sign-in-text string, $CODER_OIDC_SIGN_IN_TEXT (default: OpenID Connect)
|
||||
The text to show on the OpenID Connect sign in button.
|
||||
|
||||
--oidc-icon-url url, $CODER_OIDC_ICON_URL
|
||||
URL pointing to the icon to use on the OepnID Connect login button.
|
||||
|
||||
[1mProvisioning Options[0m
|
||||
Tune the behavior of the provisioner, which is responsible for creating,
|
||||
updating, and deleting workspace resources.
|
||||
|
||||
--provisioner-force-cancel-interval duration, $CODER_PROVISIONER_FORCE_CANCEL_INTERVAL (default: 10m0s)
|
||||
Time to force cancel provisioning tasks that are stuck.
|
||||
|
||||
--provisioner-daemon-poll-interval duration, $CODER_PROVISIONER_DAEMON_POLL_INTERVAL (default: 1s)
|
||||
Time to wait before polling for a new job.
|
||||
|
||||
--provisioner-daemon-poll-jitter duration, $CODER_PROVISIONER_DAEMON_POLL_JITTER (default: 100ms)
|
||||
Random jitter added to the poll interval.
|
||||
|
||||
--provisioner-daemons int, $CODER_PROVISIONER_DAEMONS (default: 3)
|
||||
Number of provisioner daemons to create on start. If builds are stuck
|
||||
in queued state for a long time, consider increasing this.
|
||||
|
||||
[1mTelemetry Options[0m
|
||||
Telemetry is critical to our ability to improve Coder. We strip all
|
||||
personalinformation before sending data to our servers. Please only disable
|
||||
telemetrywhen required by your organization's security policy.
|
||||
|
||||
--telemetry bool, $CODER_TELEMETRY_ENABLE (default: false)
|
||||
Whether telemetry is enabled or not. Coder collects anonymized usage
|
||||
data to help improve our product.
|
||||
|
||||
--telemetry-trace bool, $CODER_TELEMETRY_TRACE (default: false)
|
||||
Whether Opentelemetry traces are sent to Coder. Coder collects
|
||||
anonymized application tracing to help improve our product. Disabling
|
||||
telemetry also disables this option.
|
||||
|
||||
[1m⚠️ Dangerous Options[0m
|
||||
--dangerous-allow-path-app-sharing bool, $CODER_DANGEROUS_ALLOW_PATH_APP_SHARING
|
||||
Allow workspace apps that are not served from subdomains to be shared.
|
||||
Path-based app sharing is DISABLED by default for security purposes.
|
||||
Path-based apps can make requests to the Coder API and pose a security
|
||||
risk when the workspace serves malicious JavaScript. Path-based apps
|
||||
can be disabled entirely with --disable-path-apps for further
|
||||
security.
|
||||
|
||||
--dangerous-allow-path-app-site-owner-access bool, $CODER_DANGEROUS_ALLOW_PATH_APP_SITE_OWNER_ACCESS
|
||||
Allow site-owners to access workspace apps from workspaces they do not
|
||||
own. Owners cannot access path-based apps they do not own by default.
|
||||
Path-based apps can make requests to the Coder API and pose a security
|
||||
risk when the workspace serves malicious JavaScript. Path-based apps
|
||||
can be disabled entirely with --disable-path-apps for further
|
||||
security.
|
||||
|
||||
[1mEnterprise Options[0m
|
||||
These options are only available in the Enterprise Edition.
|
||||
|
||||
--browser-only bool, $CODER_BROWSER_ONLY
|
||||
Whether Coder only allows connections to workspaces via the browser.
|
||||
|
||||
--derp-server-relay-url url, $CODER_DERP_SERVER_RELAY_URL
|
||||
An HTTP URL that is accessible by other replicas to relay DERP
|
||||
traffic. Required for high availability.
|
||||
|
||||
--scim-auth-header string, $CODER_SCIM_AUTH_HEADER
|
||||
Enables SCIM and sets the authentication header for the built-in SCIM
|
||||
server. New users are automatically created with OIDC authentication.
|
||||
|
||||
---
|
||||
Run `coder --help` for a list of global options.
|
|
@ -0,0 +1,32 @@
|
|||
Usage: coder server create-admin-user [flags]
|
||||
|
||||
Create a new admin user with the given username, email and password and adds it
|
||||
to every organization.
|
||||
|
||||
[1mOptions[0m
|
||||
--email string, $CODER_EMAIL
|
||||
The email of the new user. If not specified, you will be prompted via
|
||||
stdin.
|
||||
|
||||
--password string, $CODER_PASSWORD
|
||||
The password of the new user. If not specified, you will be prompted
|
||||
via stdin.
|
||||
|
||||
--postgres-url string, $CODER_PG_CONNECTION_URL
|
||||
URL of a PostgreSQL database. If empty, the built-in PostgreSQL
|
||||
deployment will be used (Coder must not be already running in this
|
||||
case).
|
||||
|
||||
--raw-url bool
|
||||
Output the raw connection URL instead of a psql command.
|
||||
|
||||
--ssh-keygen-algorithm string, $CODER_SSH_KEYGEN_ALGORITHM (default: ed25519)
|
||||
The algorithm to use for generating ssh keys. Accepted values are
|
||||
"ed25519", "ecdsa", or "rsa4096".
|
||||
|
||||
--username string, $CODER_USERNAME
|
||||
The username of the new user. If not specified, you will be prompted
|
||||
via stdin.
|
||||
|
||||
---
|
||||
Run `coder --help` for a list of global options.
|
|
@ -0,0 +1,10 @@
|
|||
Usage: coder server postgres-builtin-serve [flags]
|
||||
|
||||
Run the built-in PostgreSQL deployment.
|
||||
|
||||
[1mOptions[0m
|
||||
--raw-url bool
|
||||
Output the raw connection URL instead of a psql command.
|
||||
|
||||
---
|
||||
Run `coder --help` for a list of global options.
|
|
@ -0,0 +1,10 @@
|
|||
Usage: coder server postgres-builtin-url [flags]
|
||||
|
||||
Output the connection URL for the built-in PostgreSQL deployment.
|
||||
|
||||
[1mOptions[0m
|
||||
--raw-url bool
|
||||
Output the raw connection URL instead of a psql command.
|
||||
|
||||
---
|
||||
Run `coder --help` for a list of global options.
|
|
@ -0,0 +1,17 @@
|
|||
Usage: coder workspace-proxy
|
||||
|
||||
Manage workspace proxies
|
||||
|
||||
Aliases: wsproxy
|
||||
|
||||
[1mSubcommands[0m
|
||||
create Create a workspace proxy
|
||||
delete Delete a workspace proxy
|
||||
edit Edit a workspace proxy
|
||||
ls List all workspace proxies
|
||||
regenerate-token Regenerate a workspace proxy authentication token. This
|
||||
will invalidate the existing authentication token.
|
||||
server Start a workspace proxy server
|
||||
|
||||
---
|
||||
Run `coder --help` for a list of global options.
|
Loading…
Reference in New Issue