Skip to content

Commit c5fb83b

Browse files
committed
feat(coderd): add endpoint for matched provisioners of template version dry run, hook up to cli
1 parent c4295ef commit c5fb83b

File tree

8 files changed

+233
-0
lines changed

8 files changed

+233
-0
lines changed

cli/create.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,12 @@ func prepWorkspaceBuild(inv *serpent.Invocation, client *codersdk.Client, args p
436436
if err != nil {
437437
return nil, xerrors.Errorf("begin workspace dry-run: %w", err)
438438
}
439+
440+
matchedProvisioners, err := client.TemplateVersionDryRunMatchedProvisioners(inv.Context(), templateVersion.ID, dryRun.ID)
441+
if err != nil {
442+
return nil, xerrors.Errorf("get matched provisioners: %w", err)
443+
}
444+
cliutil.WarnMatchedProvisioners(inv.Stdout, &matchedProvisioners, dryRun)
439445
_, _ = fmt.Fprintln(inv.Stdout, "Planning workspace...")
440446
err = cliui.ProvisionerJob(inv.Context(), inv.Stdout, cliui.ProvisionerJobOptions{
441447
Fetch: func() (codersdk.ProvisionerJob, error) {

coderd/apidoc/docs.go

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

coderd/apidoc/swagger.json

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

coderd/coderd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,7 @@ func New(options *Options) *API {
10551055
r.Get("/{jobID}", api.templateVersionDryRun)
10561056
r.Get("/{jobID}/resources", api.templateVersionDryRunResources)
10571057
r.Get("/{jobID}/logs", api.templateVersionDryRunLogs)
1058+
r.Get("/{jobID}/matched-provisioners", api.templateVersionDryRunMatchedProvisioners)
10581059
r.Patch("/{jobID}/cancel", api.patchTemplateVersionDryRunCancel)
10591060
})
10601061
})

coderd/templateversions.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,44 @@ func (api *API) templateVersionDryRun(rw http.ResponseWriter, r *http.Request) {
580580
httpapi.Write(ctx, rw, http.StatusOK, convertProvisionerJob(job))
581581
}
582582

583+
// @Summary Get template version dry-run matched provisioners
584+
// @ID get-template-version-dry-run-matched-provisioners
585+
// @Security CoderSessionToken
586+
// @Produce json
587+
// @Tags Templates
588+
// @Param templateversion path string true "Template version ID" format(uuid)
589+
// @Param jobID path string true "Job ID" format(uuid)
590+
// @Success 200 {object} codersdk.MatchedProvisioners
591+
// @Router /templateversions/{templateversion}/dry-run/{jobID}/matched-provisioners [get]
592+
func (api *API) templateVersionDryRunMatchedProvisioners(rw http.ResponseWriter, r *http.Request) {
593+
ctx := r.Context()
594+
job, ok := api.fetchTemplateVersionDryRunJob(rw, r)
595+
if !ok {
596+
return
597+
}
598+
599+
// nolint:gocritic // The user may not have permissions to read all
600+
// provisioner daemons in the org.
601+
daemons, err := api.Database.GetProvisionerDaemonsByOrganization(dbauthz.AsSystemReadProvisionerDaemons(ctx), database.GetProvisionerDaemonsByOrganizationParams{
602+
OrganizationID: job.ProvisionerJob.OrganizationID,
603+
WantTags: job.ProvisionerJob.Tags,
604+
})
605+
if err != nil {
606+
if !errors.Is(err, sql.ErrNoRows) {
607+
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
608+
Message: "Internal error fetching provisioner daemons by organization.",
609+
Detail: err.Error(),
610+
})
611+
return
612+
} else {
613+
daemons = []database.ProvisionerDaemon{}
614+
}
615+
}
616+
617+
matchedProvisioners := db2sdk.MatchedProvisioners(daemons, dbtime.Now(), provisionerdserver.StaleInterval)
618+
httpapi.Write(ctx, rw, http.StatusOK, matchedProvisioners)
619+
}
620+
583621
// @Summary Get template version dry-run resources by job ID
584622
// @ID get-template-version-dry-run-resources-by-job-id
585623
// @Security CoderSessionToken

coderd/templateversions_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,13 @@ func TestTemplateVersionDryRun(t *testing.T) {
10041004
require.NoError(t, err)
10051005
require.Equal(t, job.ID, newJob.ID)
10061006

1007+
// Check matched provisioners
1008+
matched, err := client.TemplateVersionDryRunMatchedProvisioners(ctx, version.ID, job.ID)
1009+
require.NoError(t, err)
1010+
require.Equal(t, 1, matched.Count)
1011+
require.Equal(t, 1, matched.Available)
1012+
require.NotZero(t, matched.MostRecentlySeen.Time)
1013+
10071014
// Stream logs
10081015
logs, closer, err := client.TemplateVersionDryRunLogsAfter(ctx, version.ID, job.ID, 0)
10091016
require.NoError(t, err)
@@ -1176,6 +1183,49 @@ func TestTemplateVersionDryRun(t *testing.T) {
11761183
require.Equal(t, http.StatusBadRequest, apiErr.StatusCode())
11771184
})
11781185
})
1186+
1187+
t.Run("Pending", func(t *testing.T) {
1188+
t.Parallel()
1189+
if !dbtestutil.WillUsePostgres() {
1190+
t.Skip("this test requires postgres")
1191+
}
1192+
1193+
store, ps, db := dbtestutil.NewDBWithSQLDB(t)
1194+
client, closer := coderdtest.NewWithProvisionerCloser(t, &coderdtest.Options{
1195+
Database: store,
1196+
Pubsub: ps,
1197+
IncludeProvisionerDaemon: true,
1198+
})
1199+
defer closer.Close()
1200+
1201+
owner := coderdtest.CreateFirstUser(t, client)
1202+
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, &echo.Responses{
1203+
Parse: echo.ParseComplete,
1204+
ProvisionApply: echo.ApplyComplete,
1205+
})
1206+
version = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
1207+
require.Equal(t, codersdk.ProvisionerJobSucceeded, version.Job.Status)
1208+
1209+
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
1210+
ctx := testutil.Context(t, testutil.WaitShort)
1211+
1212+
_, err := db.Exec("DELETE FROM provisioner_daemons")
1213+
require.NoError(t, err)
1214+
1215+
job, err := templateAdmin.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{
1216+
WorkspaceName: "test",
1217+
RichParameterValues: []codersdk.WorkspaceBuildParameter{},
1218+
UserVariableValues: []codersdk.VariableValue{},
1219+
})
1220+
require.NoError(t, err)
1221+
require.Equal(t, codersdk.ProvisionerJobPending, job.Status)
1222+
1223+
matched, err := templateAdmin.TemplateVersionDryRunMatchedProvisioners(ctx, version.ID, job.ID)
1224+
require.NoError(t, err)
1225+
require.Equal(t, 0, matched.Count)
1226+
require.Equal(t, 0, matched.Available)
1227+
require.Zero(t, matched.MostRecentlySeen.Time)
1228+
})
11791229
}
11801230

11811231
// TestPaginatedTemplateVersions creates a list of template versions and paginate.

codersdk/templateversions.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,22 @@ func (c *Client) TemplateVersionDryRun(ctx context.Context, version, job uuid.UU
224224
return j, json.NewDecoder(res.Body).Decode(&j)
225225
}
226226

227+
// TemplateVersionDryRunMatchedProvisioners returns the matched provisioners for a
228+
// template version dry-run job.
229+
func (c *Client) TemplateVersionDryRunMatchedProvisioners(ctx context.Context, version, job uuid.UUID) (MatchedProvisioners, error) {
230+
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/dry-run/%s/matched-provisioners", version, job), nil)
231+
if err != nil {
232+
return MatchedProvisioners{}, err
233+
}
234+
defer res.Body.Close()
235+
if res.StatusCode != http.StatusOK {
236+
return MatchedProvisioners{}, ReadBodyAsError(res)
237+
}
238+
239+
var matched MatchedProvisioners
240+
return matched, json.NewDecoder(res.Body).Decode(&matched)
241+
}
242+
227243
// TemplateVersionDryRunResources returns the resources of a finished template
228244
// version dry-run job.
229245
func (c *Client) TemplateVersionDryRunResources(ctx context.Context, version, job uuid.UUID) ([]WorkspaceResource, error) {

docs/reference/api/templates.md

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

0 commit comments

Comments
 (0)