feat: Implement parameters list + more template list columns (#2359)

* feat: Implement parameters list

- Allow more columns on template list

* Hide param list by default for now
This commit is contained in:
Steven Masley
2022-06-15 18:21:01 -05:00
committed by GitHub
parent f5e558c4ec
commit 75205f5978
8 changed files with 186 additions and 30 deletions

54
cli/parameters.go Normal file
View File

@ -0,0 +1,54 @@
package cli
import (
"github.com/jedib0t/go-pretty/v6/table"
"github.com/spf13/cobra"
"github.com/coder/coder/cli/cliui"
"github.com/coder/coder/codersdk"
)
func parameters() *cobra.Command {
cmd := &cobra.Command{
Short: "List parameters for a given scope",
Example: "coder parameters list workspace my-workspace",
Use: "parameters",
// Currently hidden as this shows parameter values, not parameter
// schemes. Until we have a good way to distinguish the two, it's better
// not to add confusion or lock ourselves into a certain api.
// This cmd is still valuable debugging tool for devs to avoid
// constructing curl requests.
Hidden: true,
Aliases: []string{"params"},
}
cmd.AddCommand(
parameterList(),
)
return cmd
}
// displayParameters will return a table displaying all parameters passed in.
// filterColumns must be a subset of the parameter fields and will determine which
// columns to display
func displayParameters(filterColumns []string, params ...codersdk.Parameter) string {
tableWriter := cliui.Table()
header := table.Row{"id", "scope", "scope id", "name", "source scheme", "destination scheme", "created at", "updated at"}
tableWriter.AppendHeader(header)
tableWriter.SetColumnConfigs(cliui.FilterTableColumns(header, filterColumns))
tableWriter.SortBy([]table.SortBy{{
Name: "name",
}})
for _, param := range params {
tableWriter.AppendRow(table.Row{
param.ID.String(),
param.Scope,
param.ScopeID.String(),
param.Name,
param.SourceScheme,
param.DestinationScheme,
param.CreatedAt,
param.UpdatedAt,
})
}
return tableWriter.Render()
}

73
cli/parameterslist.go Normal file
View File

@ -0,0 +1,73 @@
package cli
import (
"fmt"
"github.com/google/uuid"
"github.com/spf13/cobra"
"golang.org/x/xerrors"
"github.com/coder/coder/codersdk"
)
func parameterList() *cobra.Command {
var (
columns []string
)
cmd := &cobra.Command{
Use: "list",
Aliases: []string{"ls"},
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
scope, name := args[0], args[1]
client, err := createClient(cmd)
if err != nil {
return err
}
organization, err := currentOrganization(cmd, client)
if err != nil {
return xerrors.Errorf("get current organization: %w", err)
}
var scopeID uuid.UUID
switch codersdk.ParameterScope(scope) {
case codersdk.ParameterWorkspace:
workspace, err := namedWorkspace(cmd, client, name)
if err != nil {
return err
}
scopeID = workspace.ID
case codersdk.ParameterTemplate:
template, err := client.TemplateByName(cmd.Context(), organization.ID, name)
if err != nil {
return xerrors.Errorf("get workspace template: %w", err)
}
scopeID = template.ID
case codersdk.ParameterScopeImportJob, "template_version":
scope = string(codersdk.ParameterScopeImportJob)
scopeID, err = uuid.Parse(name)
if err != nil {
return xerrors.Errorf("%q must be a uuid for this scope type", name)
}
default:
return xerrors.Errorf("%q is an unsupported scope, use %v", scope, []codersdk.ParameterScope{
codersdk.ParameterWorkspace, codersdk.ParameterTemplate, codersdk.ParameterScopeImportJob,
})
}
params, err := client.Parameters(cmd.Context(), codersdk.ParameterScope(scope), scopeID)
if err != nil {
return xerrors.Errorf("fetch params: %w", err)
}
_, err = fmt.Fprintln(cmd.OutOrStdout(), displayParameters(columns, params...))
return err
},
}
cmd.Flags().StringArrayVarP(&columns, "column", "c", []string{"name", "source_scheme", "destination_scheme"},
"Specify a column to filter in the table.")
return cmd
}

View File

@ -90,6 +90,7 @@ func Root() *cobra.Command {
portForward(), portForward(),
workspaceAgent(), workspaceAgent(),
versionCmd(), versionCmd(),
parameters(),
) )
cmd.SetUsageTemplate(usageTemplate()) cmd.SetUsageTemplate(usageTemplate())

View File

@ -4,14 +4,14 @@ import (
"fmt" "fmt"
"github.com/fatih/color" "github.com/fatih/color"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/coder/coder/cli/cliui"
) )
func templateList() *cobra.Command { func templateList() *cobra.Command {
return &cobra.Command{ var (
columns []string
)
cmd := &cobra.Command{
Use: "list", Use: "list",
Aliases: []string{"ls"}, Aliases: []string{"ls"},
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
@ -34,22 +34,11 @@ func templateList() *cobra.Command {
return nil return nil
} }
tableWriter := cliui.Table() _, err = fmt.Fprintln(cmd.OutOrStdout(), displayTemplates(columns, templates...))
tableWriter.AppendHeader(table.Row{"Name", "Last updated", "Used by"})
for _, template := range templates {
suffix := ""
if template.WorkspaceOwnerCount != 1 {
suffix = "s"
}
tableWriter.AppendRow(table.Row{
template.Name,
template.UpdatedAt.Format("January 2, 2006"),
cliui.Styles.Fuschia.Render(fmt.Sprintf("%d developer%s", template.WorkspaceOwnerCount, suffix)),
})
}
_, err = fmt.Fprintln(cmd.OutOrStdout(), tableWriter.Render())
return err return err
}, },
} }
cmd.Flags().StringArrayVarP(&columns, "column", "c", []string{"name", "last_updated", "used_by"},
"Specify a column to filter in the table.")
return cmd
} }

View File

@ -1,9 +1,14 @@
package cli package cli
import ( import (
"fmt"
"time"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/coder/coder/cli/cliui" "github.com/coder/coder/cli/cliui"
"github.com/coder/coder/codersdk"
) )
func templates() *cobra.Command { func templates() *cobra.Command {
@ -38,3 +43,36 @@ func templates() *cobra.Command {
return cmd return cmd
} }
// displayTemplates will return a table displaying all templates passed in.
// filterColumns must be a subset of the template fields and will determine which
// columns to display
func displayTemplates(filterColumns []string, templates ...codersdk.Template) string {
tableWriter := cliui.Table()
header := table.Row{
"Name", "Created At", "Last Updated", "Organization ID", "Provisioner",
"Active Version ID", "Used By", "Max TTL", "Min Autostart"}
tableWriter.AppendHeader(header)
tableWriter.SetColumnConfigs(cliui.FilterTableColumns(header, filterColumns))
tableWriter.SortBy([]table.SortBy{{
Name: "name",
}})
for _, template := range templates {
suffix := ""
if template.WorkspaceOwnerCount != 1 {
suffix = "s"
}
tableWriter.AppendRow(table.Row{
template.Name,
template.CreatedAt.Format("January 2, 2006"),
template.UpdatedAt.Format("January 2, 2006"),
template.OrganizationID.String(),
template.Provisioner,
template.ActiveVersionID.String(),
cliui.Styles.Fuschia.Render(fmt.Sprintf("%d developer%s", template.WorkspaceOwnerCount, suffix)),
(time.Duration(template.MaxTTLMillis) * time.Millisecond).String(),
(time.Duration(template.MinAutostartIntervalMillis) * time.Millisecond).String(),
})
}
return tableWriter.Render()
}

View File

@ -30,7 +30,7 @@ func users() *cobra.Command {
// columns to display // columns to display
func displayUsers(filterColumns []string, users ...codersdk.User) string { func displayUsers(filterColumns []string, users ...codersdk.User) string {
tableWriter := cliui.Table() tableWriter := cliui.Table()
header := table.Row{"id", "username", "email", "created_at", "status"} header := table.Row{"id", "username", "email", "created at", "status"}
tableWriter.AppendHeader(header) tableWriter.AppendHeader(header)
tableWriter.SetColumnConfigs(cliui.FilterTableColumns(header, filterColumns)) tableWriter.SetColumnConfigs(cliui.FilterTableColumns(header, filterColumns))
tableWriter.SortBy([]table.SortBy{{ tableWriter.SortBy([]table.SortBy{{

View File

@ -16,6 +16,7 @@ type ParameterScope string
const ( const (
ParameterTemplate ParameterScope = "template" ParameterTemplate ParameterScope = "template"
ParameterWorkspace ParameterScope = "workspace" ParameterWorkspace ParameterScope = "workspace"
ParameterScopeImportJob ParameterScope = "import_job"
) )
type ParameterSourceScheme string type ParameterSourceScheme string

View File

@ -49,7 +49,7 @@ export interface CreateOrganizationRequest {
readonly name: string readonly name: string
} }
// From codersdk/parameters.go:79:6 // From codersdk/parameters.go:80:6
export interface CreateParameterRequest { export interface CreateParameterRequest {
readonly name: string readonly name: string
readonly source_value: string readonly source_value: string
@ -160,7 +160,7 @@ export interface Pagination {
readonly offset?: number readonly offset?: number
} }
// From codersdk/parameters.go:44:6 // From codersdk/parameters.go:45:6
export interface Parameter { export interface Parameter {
readonly id: string readonly id: string
readonly created_at: string readonly created_at: string
@ -172,7 +172,7 @@ export interface Parameter {
readonly destination_scheme: ParameterDestinationScheme readonly destination_scheme: ParameterDestinationScheme
} }
// From codersdk/parameters.go:55:6 // From codersdk/parameters.go:56:6
export interface ParameterSchema { export interface ParameterSchema {
readonly id: string readonly id: string
readonly created_at: string readonly created_at: string
@ -494,16 +494,16 @@ export type LogLevel = "debug" | "error" | "info" | "trace" | "warn"
// From codersdk/provisionerdaemons.go:16:6 // From codersdk/provisionerdaemons.go:16:6
export type LogSource = "provisioner" | "provisioner_daemon" export type LogSource = "provisioner" | "provisioner_daemon"
// From codersdk/parameters.go:28:6 // From codersdk/parameters.go:29:6
export type ParameterDestinationScheme = "environment_variable" | "none" | "provisioner_variable" export type ParameterDestinationScheme = "environment_variable" | "none" | "provisioner_variable"
// From codersdk/parameters.go:14:6 // From codersdk/parameters.go:14:6
export type ParameterScope = "template" | "workspace" export type ParameterScope = "import_job" | "template" | "workspace"
// From codersdk/parameters.go:21:6 // From codersdk/parameters.go:22:6
export type ParameterSourceScheme = "data" | "none" export type ParameterSourceScheme = "data" | "none"
// From codersdk/parameters.go:36:6 // From codersdk/parameters.go:37:6
export type ParameterTypeSystem = "hcl" | "none" export type ParameterTypeSystem = "hcl" | "none"
// From codersdk/provisionerdaemons.go:42:6 // From codersdk/provisionerdaemons.go:42:6