diff --git a/cli/organization.go b/cli/organization.go
index 528f9f0d34..6ebd28f9ff 100644
--- a/cli/organization.go
+++ b/cli/organization.go
@@ -23,6 +23,7 @@ func (r *RootCmd) organizations() *serpent.Command {
},
Children: []*serpent.Command{
r.showOrganization(orgContext),
+ r.listOrganizations(),
r.createOrganization(),
r.deleteOrganization(orgContext),
r.organizationMembers(orgContext),
diff --git a/cli/organization_test.go b/cli/organization_test.go
index 83f49b9cb7..8c4997f4ae 100644
--- a/cli/organization_test.go
+++ b/cli/organization_test.go
@@ -1,6 +1,7 @@
package cli_test
import (
+ "bytes"
"encoding/json"
"fmt"
"net/http"
@@ -58,6 +59,48 @@ func TestCurrentOrganization(t *testing.T) {
})
}
+func TestOrganizationList(t *testing.T) {
+ t.Parallel()
+
+ t.Run("OK", func(t *testing.T) {
+ t.Parallel()
+
+ orgID := uuid.New()
+ server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ switch {
+ case r.Method == http.MethodGet && r.URL.Path == "/api/v2/organizations":
+ _ = json.NewEncoder(w).Encode([]codersdk.Organization{
+ {
+ MinimalOrganization: codersdk.MinimalOrganization{
+ ID: orgID,
+ Name: "my-org",
+ DisplayName: "My Org",
+ },
+ CreatedAt: time.Now(),
+ UpdatedAt: time.Now(),
+ },
+ })
+ default:
+ t.Errorf("unexpected request: %s %s", r.Method, r.URL.Path)
+ w.WriteHeader(http.StatusNotFound)
+ }
+ }))
+ defer server.Close()
+
+ client := codersdk.New(must(url.Parse(server.URL)))
+ inv, root := clitest.New(t, "organizations", "list")
+ clitest.SetupConfig(t, client, root)
+
+ buf := new(bytes.Buffer)
+ inv.Stdout = buf
+
+ require.NoError(t, inv.Run())
+ require.Contains(t, buf.String(), "my-org")
+ require.Contains(t, buf.String(), "My Org")
+ require.Contains(t, buf.String(), orgID.String())
+ })
+}
+
func TestOrganizationDelete(t *testing.T) {
t.Parallel()
diff --git a/cli/organizationlist.go b/cli/organizationlist.go
new file mode 100644
index 0000000000..e943e76478
--- /dev/null
+++ b/cli/organizationlist.go
@@ -0,0 +1,53 @@
+package cli
+
+import (
+ "fmt"
+
+ "github.com/coder/coder/v2/cli/cliui"
+ "github.com/coder/coder/v2/codersdk"
+ "github.com/coder/serpent"
+)
+
+func (r *RootCmd) listOrganizations() *serpent.Command {
+ formatter := cliui.NewOutputFormatter(
+ cliui.TableFormat([]codersdk.Organization{}, []string{"name", "display name", "id", "default"}),
+ cliui.JSONFormat(),
+ )
+
+ cmd := &serpent.Command{
+ Use: "list",
+ Short: "List all organizations",
+ Long: "List all organizations. Requires a role which grants ResourceOrganization: read.",
+ Aliases: []string{"ls"},
+ Middleware: serpent.Chain(
+ serpent.RequireNArgs(0),
+ ),
+ Handler: func(inv *serpent.Invocation) error {
+ client, err := r.InitClient(inv)
+ if err != nil {
+ return err
+ }
+
+ organizations, err := client.Organizations(inv.Context())
+ if err != nil {
+ return err
+ }
+
+ out, err := formatter.Format(inv.Context(), organizations)
+ if err != nil {
+ return err
+ }
+
+ if out == "" {
+ cliui.Infof(inv.Stderr, "No organizations found.")
+ return nil
+ }
+
+ _, err = fmt.Fprintln(inv.Stdout, out)
+ return err
+ },
+ }
+
+ formatter.AttachOptions(&cmd.Options)
+ return cmd
+}
diff --git a/cli/testdata/coder_organizations_--help.golden b/cli/testdata/coder_organizations_--help.golden
index 417ba5edb9..46f5d56a21 100644
--- a/cli/testdata/coder_organizations_--help.golden
+++ b/cli/testdata/coder_organizations_--help.golden
@@ -10,6 +10,7 @@ USAGE:
SUBCOMMANDS:
create Create a new organization.
delete Delete an organization
+ list List all organizations
members Manage organization members
roles Manage organization roles.
settings Manage organization settings.
diff --git a/cli/testdata/coder_organizations_list_--help.golden b/cli/testdata/coder_organizations_list_--help.golden
new file mode 100644
index 0000000000..8197886411
--- /dev/null
+++ b/cli/testdata/coder_organizations_list_--help.golden
@@ -0,0 +1,21 @@
+coder v0.0.0-devel
+
+USAGE:
+ coder organizations list [flags]
+
+ List all organizations
+
+ Aliases: ls
+
+ List all organizations. Requires a role which grants ResourceOrganization:
+ read.
+
+OPTIONS:
+ -c, --column [id|name|display name|icon|description|created at|updated at|default] (default: name,display name,id,default)
+ Columns to display in table output.
+
+ -o, --output table|json (default: table)
+ Output format.
+
+———
+Run `coder --help` for a list of global options.
diff --git a/docs/manifest.json b/docs/manifest.json
index c669a58cfb..84b7c4428f 100644
--- a/docs/manifest.json
+++ b/docs/manifest.json
@@ -1637,6 +1637,11 @@
"description": "Delete an organization",
"path": "reference/cli/organizations_delete.md"
},
+ {
+ "title": "organizations list",
+ "description": "List all organizations",
+ "path": "reference/cli/organizations_list.md"
+ },
{
"title": "organizations members",
"description": "Manage organization members",
diff --git a/docs/reference/cli/organizations.md b/docs/reference/cli/organizations.md
index 0d4cc7f6a2..e487735e8c 100644
--- a/docs/reference/cli/organizations.md
+++ b/docs/reference/cli/organizations.md
@@ -20,6 +20,7 @@ coder organizations [flags] [subcommand]
| Name | Purpose |
|------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [show](./organizations_show.md) | Show the organization. Using "selected" will show the selected organization from the "--org" flag. Using "me" will show all organizations you are a member of. |
+| [list](./organizations_list.md) | List all organizations |
| [create](./organizations_create.md) | Create a new organization. |
| [delete](./organizations_delete.md) | Delete an organization |
| [members](./organizations_members.md) | Manage organization members |
diff --git a/docs/reference/cli/organizations_list.md b/docs/reference/cli/organizations_list.md
new file mode 100644
index 0000000000..5f866caf5a
--- /dev/null
+++ b/docs/reference/cli/organizations_list.md
@@ -0,0 +1,40 @@
+
+# organizations list
+
+List all organizations
+
+Aliases:
+
+* ls
+
+## Usage
+
+```console
+coder organizations list [flags]
+```
+
+## Description
+
+```console
+List all organizations. Requires a role which grants ResourceOrganization: read.
+```
+
+## Options
+
+### -c, --column
+
+| | |
+|---------|-------------------------------------------------------------------------------------------|
+| Type | [id\|name\|display name\|icon\|description\|created at\|updated at\|default] |
+| Default | name,display name,id,default |
+
+Columns to display in table output.
+
+### -o, --output
+
+| | |
+|---------|--------------------------|
+| Type | table\|json |
+| Default | table |
+
+Output format.