diff --git a/cli/parameters.go b/cli/parameters.go new file mode 100644 index 0000000000000..cc5607247012b --- /dev/null +++ b/cli/parameters.go @@ -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() +} diff --git a/cli/parameterslist.go b/cli/parameterslist.go new file mode 100644 index 0000000000000..8955ba96ca0c3 --- /dev/null +++ b/cli/parameterslist.go @@ -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 +} diff --git a/cli/root.go b/cli/root.go index cb59816fe10ec..087f052a2a377 100644 --- a/cli/root.go +++ b/cli/root.go @@ -90,6 +90,7 @@ func Root() *cobra.Command { portForward(), workspaceAgent(), versionCmd(), + parameters(), ) cmd.SetUsageTemplate(usageTemplate()) diff --git a/cli/templatelist.go b/cli/templatelist.go index 41760599e415a..a8a1315a1f0c9 100644 --- a/cli/templatelist.go +++ b/cli/templatelist.go @@ -4,14 +4,14 @@ import ( "fmt" "github.com/fatih/color" - "github.com/jedib0t/go-pretty/v6/table" "github.com/spf13/cobra" - - "github.com/coder/coder/cli/cliui" ) func templateList() *cobra.Command { - return &cobra.Command{ + var ( + columns []string + ) + cmd := &cobra.Command{ Use: "list", Aliases: []string{"ls"}, RunE: func(cmd *cobra.Command, args []string) error { @@ -34,22 +34,11 @@ func templateList() *cobra.Command { return nil } - tableWriter := cliui.Table() - 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()) + _, err = fmt.Fprintln(cmd.OutOrStdout(), displayTemplates(columns, templates...)) return err }, } + cmd.Flags().StringArrayVarP(&columns, "column", "c", []string{"name", "last_updated", "used_by"}, + "Specify a column to filter in the table.") + return cmd } diff --git a/cli/templates.go b/cli/templates.go index c737bb6c134c0..66d6f224f171b 100644 --- a/cli/templates.go +++ b/cli/templates.go @@ -1,9 +1,14 @@ package cli import ( + "fmt" + "time" + + "github.com/jedib0t/go-pretty/v6/table" "github.com/spf13/cobra" "github.com/coder/coder/cli/cliui" + "github.com/coder/coder/codersdk" ) func templates() *cobra.Command { @@ -17,7 +22,7 @@ func templates() *cobra.Command { ` + cliui.Styles.Code.Render("$ coder templates create") + ` - Make changes to your template, and plan the changes - + ` + cliui.Styles.Code.Render("$ coder templates plan ") + ` - Update the template. Your developers can update their workspaces @@ -37,3 +42,36 @@ func templates() *cobra.Command { 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() +} diff --git a/cli/users.go b/cli/users.go index 3bbb3067fbd92..80df42ebf6787 100644 --- a/cli/users.go +++ b/cli/users.go @@ -30,7 +30,7 @@ func users() *cobra.Command { // columns to display func displayUsers(filterColumns []string, users ...codersdk.User) string { 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.SetColumnConfigs(cliui.FilterTableColumns(header, filterColumns)) tableWriter.SortBy([]table.SortBy{{ diff --git a/codersdk/parameters.go b/codersdk/parameters.go index 073efafb63fbb..d1e8869c59514 100644 --- a/codersdk/parameters.go +++ b/codersdk/parameters.go @@ -14,8 +14,9 @@ import ( type ParameterScope string const ( - ParameterTemplate ParameterScope = "template" - ParameterWorkspace ParameterScope = "workspace" + ParameterTemplate ParameterScope = "template" + ParameterWorkspace ParameterScope = "workspace" + ParameterScopeImportJob ParameterScope = "import_job" ) type ParameterSourceScheme string diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index e220103a3eba0..f548a688d9d38 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -49,7 +49,7 @@ export interface CreateOrganizationRequest { readonly name: string } -// From codersdk/parameters.go:79:6 +// From codersdk/parameters.go:80:6 export interface CreateParameterRequest { readonly name: string readonly source_value: string @@ -160,7 +160,7 @@ export interface Pagination { readonly offset?: number } -// From codersdk/parameters.go:44:6 +// From codersdk/parameters.go:45:6 export interface Parameter { readonly id: string readonly created_at: string @@ -172,7 +172,7 @@ export interface Parameter { readonly destination_scheme: ParameterDestinationScheme } -// From codersdk/parameters.go:55:6 +// From codersdk/parameters.go:56:6 export interface ParameterSchema { readonly id: string readonly created_at: string @@ -493,16 +493,16 @@ export type LogLevel = "debug" | "error" | "info" | "trace" | "warn" // From codersdk/provisionerdaemons.go:16:6 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" // 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" -// From codersdk/parameters.go:36:6 +// From codersdk/parameters.go:37:6 export type ParameterTypeSystem = "hcl" | "none" // From codersdk/provisionerdaemons.go:42:6