Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit356fb39

Browse files
committed
feat(cli): add CLI support for listing presets
1 parentaae5fc2 commit356fb39

18 files changed

+427
-11
lines changed

‎cli/templateversionpresets.go‎

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package cli
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
"strings"
7+
8+
"golang.org/x/xerrors"
9+
10+
"github.com/coder/coder/v2/cli/cliui"
11+
"github.com/coder/coder/v2/codersdk"
12+
"github.com/coder/serpent"
13+
)
14+
15+
func (r*RootCmd)templateVersionPresets()*serpent.Command {
16+
cmd:=&serpent.Command{
17+
Use:"presets",
18+
Short:"Manage presets of the specified template version",
19+
Aliases: []string{"preset"},
20+
Long:FormatExamples(
21+
Example{
22+
Description:"List presets of a specific template version",
23+
Command:"coder templates versions presets list my-template my-template-version",
24+
},
25+
),
26+
Handler:func(inv*serpent.Invocation)error {
27+
returninv.Command.HelpHandler(inv)
28+
},
29+
Children: []*serpent.Command{
30+
r.templateVersionPresetsList(),
31+
},
32+
}
33+
34+
returncmd
35+
}
36+
37+
func (r*RootCmd)templateVersionPresetsList()*serpent.Command {
38+
defaultColumns:= []string{
39+
"name",
40+
"parameters",
41+
"default",
42+
"prebuilds",
43+
}
44+
formatter:=cliui.NewOutputFormatter(
45+
cliui.TableFormat([]templateVersionPresetRow{},defaultColumns),
46+
cliui.JSONFormat(),
47+
)
48+
client:=new(codersdk.Client)
49+
orgContext:=NewOrganizationContext()
50+
51+
cmd:=&serpent.Command{
52+
Use:"list <template> <version>",
53+
Middleware:serpent.Chain(
54+
serpent.RequireNArgs(2),
55+
r.InitClient(client),
56+
),
57+
Short:"List all the presets of the specified template version",
58+
Options: serpent.OptionSet{},
59+
Handler:func(inv*serpent.Invocation)error {
60+
organization,err:=orgContext.Selected(inv,client)
61+
iferr!=nil {
62+
returnxerrors.Errorf("get current organization: %w",err)
63+
}
64+
65+
template,err:=client.TemplateByName(inv.Context(),organization.ID,inv.Args[0])
66+
iferr!=nil {
67+
returnxerrors.Errorf("get template by name: %w",err)
68+
}
69+
70+
version,err:=client.TemplateVersionByName(inv.Context(),template.ID,inv.Args[1])
71+
iferr!=nil {
72+
returnxerrors.Errorf("get template version by name: %w",err)
73+
}
74+
75+
presets,err:=client.TemplateVersionPresets(inv.Context(),version.ID)
76+
iferr!=nil {
77+
returnxerrors.Errorf("get template versions presets by template version: %w",err)
78+
}
79+
80+
iflen(presets)==0 {
81+
returnxerrors.Errorf("no presets found for template %q and template-version %q",template.Name,version.Name)
82+
}
83+
84+
rows:=templateVersionPresetsToRows(presets...)
85+
out,err:=formatter.Format(inv.Context(),rows)
86+
iferr!=nil {
87+
returnxerrors.Errorf("render table: %w",err)
88+
}
89+
90+
_,err=fmt.Fprintln(inv.Stdout,out)
91+
returnerr
92+
},
93+
}
94+
95+
orgContext.AttachOptions(cmd)
96+
formatter.AttachOptions(&cmd.Options)
97+
returncmd
98+
}
99+
100+
typetemplateVersionPresetRowstruct {
101+
// For json format:
102+
TemplateVersionPreset codersdk.Preset`table:"-"`
103+
104+
// For table format:
105+
Namestring`json:"-" table:"name,default_sort"`
106+
Parametersstring`json:"-" table:"parameters"`
107+
Defaultbool`json:"-" table:"default"`
108+
Prebuildsstring`json:"-" table:"prebuilds"`
109+
}
110+
111+
funcformatPresetParameters(params []codersdk.PresetParameter)string {
112+
varparamsStr []string
113+
for_,p:=rangeparams {
114+
paramsStr=append(paramsStr,fmt.Sprintf("%s=%s",p.Name,p.Value))
115+
}
116+
returnstrings.Join(paramsStr,",")
117+
}
118+
119+
// templateVersionPresetsToRows converts a list of presets to a list of rows
120+
// for outputting.
121+
functemplateVersionPresetsToRows(presets...codersdk.Preset) []templateVersionPresetRow {
122+
rows:=make([]templateVersionPresetRow,len(presets))
123+
fori,preset:=rangepresets {
124+
prebuilds:="-"
125+
ifpreset.Prebuilds!=nil {
126+
prebuilds=strconv.Itoa(*preset.Prebuilds)
127+
}
128+
rows[i]=templateVersionPresetRow{
129+
Name:preset.Name,
130+
Parameters:formatPresetParameters(preset.Parameters),
131+
Default:preset.Default,
132+
Prebuilds:prebuilds,
133+
}
134+
}
135+
136+
returnrows
137+
}

‎cli/templateversionpresets_test.go‎

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package cli_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/coder/coder/v2/provisioner/echo"
8+
"github.com/coder/coder/v2/provisionersdk/proto"
9+
10+
"github.com/stretchr/testify/require"
11+
12+
"github.com/coder/coder/v2/cli/clitest"
13+
"github.com/coder/coder/v2/coderd/coderdtest"
14+
"github.com/coder/coder/v2/pty/ptytest"
15+
)
16+
17+
funcTestTemplateVersionPresets(t*testing.T) {
18+
t.Parallel()
19+
20+
t.Run("ListPresets",func(t*testing.T) {
21+
t.Parallel()
22+
23+
client:=coderdtest.New(t,&coderdtest.Options{IncludeProvisionerDaemon:true})
24+
owner:=coderdtest.CreateFirstUser(t,client)
25+
member,_:=coderdtest.CreateAnotherUser(t,client,owner.OrganizationID)
26+
27+
// Given: a template version that includes presets
28+
presets:= []*proto.Preset{
29+
{
30+
Name:"preset-multiple-params",
31+
Parameters: []*proto.PresetParameter{
32+
{
33+
Name:"k1",
34+
Value:"v1",
35+
}, {
36+
Name:"k2",
37+
Value:"v2",
38+
},
39+
},
40+
},
41+
{
42+
Name:"preset-default",
43+
Default:true,
44+
Parameters: []*proto.PresetParameter{
45+
{
46+
Name:"k1",
47+
Value:"v2",
48+
},
49+
},
50+
Prebuild:&proto.Prebuild{
51+
Instances:0,
52+
},
53+
},
54+
{
55+
Name:"preset-prebuilds",
56+
Parameters: []*proto.PresetParameter{},
57+
Prebuild:&proto.Prebuild{
58+
Instances:2,
59+
},
60+
},
61+
}
62+
version:=coderdtest.CreateTemplateVersion(t,client,owner.OrganizationID,templateWithPresets(presets))
63+
_=coderdtest.AwaitTemplateVersionJobCompleted(t,client,version.ID)
64+
template:=coderdtest.CreateTemplate(t,client,owner.OrganizationID,version.ID)
65+
66+
// When: listing presets for that template and template version
67+
inv,root:=clitest.New(t,"templates","versions","presets","list",template.Name,version.Name)
68+
clitest.SetupConfig(t,member,root)
69+
70+
pty:=ptytest.New(t).Attach(inv)
71+
doneChan:=make(chanstruct{})
72+
varrunErrerror
73+
gofunc() {
74+
deferclose(doneChan)
75+
runErr=inv.Run()
76+
}()
77+
78+
<-doneChan
79+
require.NoError(t,runErr)
80+
81+
// Should: return the presets sorted by name
82+
pty.ExpectRegexMatch(`preset-default\s+k1=v2\s+true\s+0`)
83+
// The parameter order is not guaranteed in the output, so we match both possible orders
84+
pty.ExpectRegexMatch(`preset-multiple-params\s+(k1=v1,k2=v2)|(k2=v2,k1=v1)\s+false\s+-`)
85+
pty.ExpectRegexMatch(`preset-prebuilds\s+\s+false\s+2`)
86+
})
87+
88+
t.Run("NoPresets",func(t*testing.T) {
89+
t.Parallel()
90+
91+
client:=coderdtest.New(t,&coderdtest.Options{IncludeProvisionerDaemon:true})
92+
owner:=coderdtest.CreateFirstUser(t,client)
93+
member,_:=coderdtest.CreateAnotherUser(t,client,owner.OrganizationID)
94+
95+
// Given: a template version without presets
96+
version:=coderdtest.CreateTemplateVersion(t,client,owner.OrganizationID,templateWithPresets([]*proto.Preset{}))
97+
_=coderdtest.AwaitTemplateVersionJobCompleted(t,client,version.ID)
98+
template:=coderdtest.CreateTemplate(t,client,owner.OrganizationID,version.ID)
99+
100+
// When: listing presets for that template and template version
101+
inv,root:=clitest.New(t,"templates","versions","presets","list",template.Name,version.Name)
102+
clitest.SetupConfig(t,member,root)
103+
104+
ptytest.New(t).Attach(inv)
105+
doneChan:=make(chanstruct{})
106+
varrunErrerror
107+
gofunc() {
108+
deferclose(doneChan)
109+
runErr=inv.Run()
110+
}()
111+
<-doneChan
112+
113+
// Should return an error when no presets are found for the given template and version.
114+
require.Error(t,runErr)
115+
expectedErr:=fmt.Sprintf(
116+
"no presets found for template %q and template-version %q",
117+
template.Name,
118+
version.Name,
119+
)
120+
require.Contains(t,runErr.Error(),expectedErr)
121+
})
122+
}
123+
124+
functemplateWithPresets(presets []*proto.Preset)*echo.Responses {
125+
return&echo.Responses{
126+
Parse:echo.ParseComplete,
127+
ProvisionPlan: []*proto.Response{
128+
{
129+
Type:&proto.Response_Plan{
130+
Plan:&proto.PlanComplete{
131+
Presets:presets,
132+
},
133+
},
134+
},
135+
},
136+
}
137+
}

‎cli/templateversions.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ func (r *RootCmd) templateVersions() *serpent.Command {
3333
r.archiveTemplateVersion(),
3434
r.unarchiveTemplateVersion(),
3535
r.templateVersionsPromote(),
36+
r.templateVersionPresets(),
3637
},
3738
}
3839

‎cli/testdata/coder_templates_versions_--help.golden‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ USAGE:
1414
SUBCOMMANDS:
1515
archive Archive a template version(s).
1616
list List all the versions of the specified template
17+
presets Manage presets of the specified template version
1718
promote Promote a template version to active.
1819
unarchive Unarchive a template version(s).
1920

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
coder v0.0.0-devel
2+
3+
USAGE:
4+
coder templates versions presets
5+
6+
Manage presets of the specified template version
7+
8+
Aliases: preset
9+
10+
- List presets of a specific template version:
11+
12+
$ coder templates versions presets list my-template my-template-version
13+
14+
SUBCOMMANDS:
15+
list List all the presets of the specified template version
16+
17+
———
18+
Run `coder --help` for a list of global options.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
coder v0.0.0-devel
2+
3+
USAGE:
4+
coder templates versions presets
5+
6+
Manage presets of the specified template version
7+
8+
Aliases: preset
9+
10+
- List presets of a specific template version:
11+
12+
$ coder templates versions presets list my-template my-template-version
13+
14+
SUBCOMMANDS:
15+
list List all the presets of the specified template version
16+
17+
———
18+
Run `coder --help` for a list of global options.

‎coderd/apidoc/docs.go‎

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/apidoc/swagger.json‎

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/presets.go‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package coderd
22

33
import (
4+
"database/sql"
45
"net/http"
56

67
"github.com/coder/coder/v2/coderd/httpapi"
@@ -38,12 +39,21 @@ func (api *API) templateVersionPresets(rw http.ResponseWriter, r *http.Request)
3839
return
3940
}
4041

42+
getPrebuildInstances:=func(desiredInstances sql.NullInt32)*int {
43+
ifdesiredInstances.Valid {
44+
value:=int(desiredInstances.Int32)
45+
return&value
46+
}
47+
returnnil
48+
}
49+
4150
varres []codersdk.Preset
4251
for_,preset:=rangepresets {
4352
sdkPreset:= codersdk.Preset{
44-
ID:preset.ID,
45-
Name:preset.Name,
46-
Default:preset.IsDefault,
53+
ID:preset.ID,
54+
Name:preset.Name,
55+
Default:preset.IsDefault,
56+
Prebuilds:getPrebuildInstances(preset.DesiredInstances),
4757
}
4858
for_,presetParam:=rangepresetParams {
4959
ifpresetParam.TemplateVersionPresetID!=preset.ID {

‎codersdk/presets.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type Preset struct {
1515
Namestring
1616
Parameters []PresetParameter
1717
Defaultbool
18+
Prebuilds*int
1819
}
1920

2021
typePresetParameterstruct {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp