feat(coderd): add matched provisioner daemons information to more places (#15688)

- Refactors `checkProvisioners` into `db2sdk.MatchedProvisioners`
- Adds a separate RBAC subject just for reading provisioner daemons
- Adds matched provisioners information to additional endpoints relating to
  workspace builds and templates
-Updates existing unit tests for above endpoints
-Adds API endpoint for matched provisioners of template dry-run job
-Updates CLI to show warning when creating/starting/stopping/deleting
 workspaces for which no provisoners are available

---------

Co-authored-by: Danny Kopping <danny@coder.com>
This commit is contained in:
Cian Johnston
2024-12-02 20:54:32 +00:00
committed by GitHub
co-authored by Danny Kopping
parent 7e1ac2e22b
commit 2b57dcc68c
30 changed files with 1058 additions and 166 deletions
+77 -2
View File
@@ -50,6 +50,12 @@ func TestTemplateVersion(t *testing.T) {
tv, err := client.TemplateVersion(ctx, version.ID)
authz.AssertChecked(t, policy.ActionRead, tv)
require.NoError(t, err)
if assert.Equal(t, tv.Job.Status, codersdk.ProvisionerJobPending) {
assert.NotNil(t, tv.MatchedProvisioners)
assert.Zero(t, tv.MatchedProvisioners.Available)
assert.Zero(t, tv.MatchedProvisioners.Count)
assert.False(t, tv.MatchedProvisioners.MostRecentlySeen.Valid)
}
assert.Equal(t, "bananas", tv.Name)
assert.Equal(t, "first try", tv.Message)
@@ -87,8 +93,14 @@ func TestTemplateVersion(t *testing.T) {
client1, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID)
_, err := client1.TemplateVersion(ctx, version.ID)
tv, err := client1.TemplateVersion(ctx, version.ID)
require.NoError(t, err)
if assert.Equal(t, tv.Job.Status, codersdk.ProvisionerJobPending) {
assert.NotNil(t, tv.MatchedProvisioners)
assert.Zero(t, tv.MatchedProvisioners.Available)
assert.Zero(t, tv.MatchedProvisioners.Count)
assert.False(t, tv.MatchedProvisioners.MostRecentlySeen.Valid)
}
})
}
@@ -158,6 +170,12 @@ func TestPostTemplateVersionsByOrganization(t *testing.T) {
require.NoError(t, err)
require.Equal(t, "bananas", version.Name)
require.Equal(t, provisionersdk.ScopeOrganization, version.Job.Tags[provisionersdk.TagScope])
if assert.Equal(t, version.Job.Status, codersdk.ProvisionerJobPending) {
assert.NotNil(t, version.MatchedProvisioners)
assert.Equal(t, version.MatchedProvisioners.Available, 1)
assert.Equal(t, version.MatchedProvisioners.Count, 1)
assert.True(t, version.MatchedProvisioners.MostRecentlySeen.Valid)
}
require.Len(t, auditor.AuditLogs(), 2)
assert.Equal(t, database.AuditActionCreate, auditor.AuditLogs()[1].Action)
@@ -790,8 +808,15 @@ func TestTemplateVersionByName(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
_, err := client.TemplateVersionByName(ctx, template.ID, version.Name)
tv, err := client.TemplateVersionByName(ctx, template.ID, version.Name)
require.NoError(t, err)
if assert.Equal(t, tv.Job.Status, codersdk.ProvisionerJobPending) {
assert.NotNil(t, tv.MatchedProvisioners)
assert.Zero(t, tv.MatchedProvisioners.Available)
assert.Zero(t, tv.MatchedProvisioners.Count)
assert.False(t, tv.MatchedProvisioners.MostRecentlySeen.Valid)
}
})
}
@@ -979,6 +1004,13 @@ func TestTemplateVersionDryRun(t *testing.T) {
require.NoError(t, err)
require.Equal(t, job.ID, newJob.ID)
// Check matched provisioners
matched, err := client.TemplateVersionDryRunMatchedProvisioners(ctx, version.ID, job.ID)
require.NoError(t, err)
require.Equal(t, 1, matched.Count)
require.Equal(t, 1, matched.Available)
require.NotZero(t, matched.MostRecentlySeen.Time)
// Stream logs
logs, closer, err := client.TemplateVersionDryRunLogsAfter(ctx, version.ID, job.ID, 0)
require.NoError(t, err)
@@ -1151,6 +1183,49 @@ func TestTemplateVersionDryRun(t *testing.T) {
require.Equal(t, http.StatusBadRequest, apiErr.StatusCode())
})
})
t.Run("Pending", func(t *testing.T) {
t.Parallel()
if !dbtestutil.WillUsePostgres() {
t.Skip("this test requires postgres")
}
store, ps, db := dbtestutil.NewDBWithSQLDB(t)
client, closer := coderdtest.NewWithProvisionerCloser(t, &coderdtest.Options{
Database: store,
Pubsub: ps,
IncludeProvisionerDaemon: true,
})
defer closer.Close()
owner := coderdtest.CreateFirstUser(t, client)
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, &echo.Responses{
Parse: echo.ParseComplete,
ProvisionApply: echo.ApplyComplete,
})
version = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
require.Equal(t, codersdk.ProvisionerJobSucceeded, version.Job.Status)
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
ctx := testutil.Context(t, testutil.WaitShort)
_, err := db.Exec("DELETE FROM provisioner_daemons")
require.NoError(t, err)
job, err := templateAdmin.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{
WorkspaceName: "test",
RichParameterValues: []codersdk.WorkspaceBuildParameter{},
UserVariableValues: []codersdk.VariableValue{},
})
require.NoError(t, err)
require.Equal(t, codersdk.ProvisionerJobPending, job.Status)
matched, err := templateAdmin.TemplateVersionDryRunMatchedProvisioners(ctx, version.ID, job.ID)
require.NoError(t, err)
require.Equal(t, 0, matched.Count)
require.Equal(t, 0, matched.Available)
require.Zero(t, matched.MostRecentlySeen.Time)
})
}
// TestPaginatedTemplateVersions creates a list of template versions and paginate.