diff --git a/coderd/database/dbauthz/dbauthz.go b/coderd/database/dbauthz/dbauthz.go
index a85b13925c298..545a94b0f678e 100644
--- a/coderd/database/dbauthz/dbauthz.go
+++ b/coderd/database/dbauthz/dbauthz.go
@@ -1930,6 +1930,33 @@ func (q *querier) GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUI
return q.db.GetParameterSchemasByJobID(ctx, jobID)
}
+func (q *querier) GetPresetByWorkspaceBuildID(ctx context.Context, workspaceID uuid.UUID) (database.TemplateVersionPreset, error) {
+ if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceTemplate); err != nil {
+ return database.TemplateVersionPreset{}, err
+ }
+ return q.db.GetPresetByWorkspaceBuildID(ctx, workspaceID)
+}
+
+func (q *querier) GetPresetParametersByTemplateVersionID(ctx context.Context, templateVersionID uuid.UUID) ([]database.TemplateVersionPresetParameter, error) {
+ // An actor can read template version presets if they can read the related template version.
+ _, err := q.GetTemplateVersionByID(ctx, templateVersionID)
+ if err != nil {
+ return nil, err
+ }
+
+ return q.db.GetPresetParametersByTemplateVersionID(ctx, templateVersionID)
+}
+
+func (q *querier) GetPresetsByTemplateVersionID(ctx context.Context, templateVersionID uuid.UUID) ([]database.TemplateVersionPreset, error) {
+ // An actor can read template version presets if they can read the related template version.
+ _, err := q.GetTemplateVersionByID(ctx, templateVersionID)
+ if err != nil {
+ return nil, err
+ }
+
+ return q.db.GetPresetsByTemplateVersionID(ctx, templateVersionID)
+}
+
func (q *querier) GetPreviousTemplateVersion(ctx context.Context, arg database.GetPreviousTemplateVersionParams) (database.TemplateVersion, error) {
// An actor can read the previous template version if they can read the related template.
// If no linked template exists, we check if the actor can read *a* template.
@@ -3088,6 +3115,24 @@ func (q *querier) InsertOrganizationMember(ctx context.Context, arg database.Ins
return insert(q.log, q.auth, obj, q.db.InsertOrganizationMember)(ctx, arg)
}
+func (q *querier) InsertPreset(ctx context.Context, arg database.InsertPresetParams) (database.TemplateVersionPreset, error) {
+ err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceTemplate)
+ if err != nil {
+ return database.TemplateVersionPreset{}, err
+ }
+
+ return q.db.InsertPreset(ctx, arg)
+}
+
+func (q *querier) InsertPresetParameters(ctx context.Context, arg database.InsertPresetParametersParams) ([]database.TemplateVersionPresetParameter, error) {
+ err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceTemplate)
+ if err != nil {
+ return nil, err
+ }
+
+ return q.db.InsertPresetParameters(ctx, arg)
+}
+
// TODO: We need to create a ProvisionerJob resource type
func (q *querier) InsertProvisionerJob(ctx context.Context, arg database.InsertProvisionerJobParams) (database.ProvisionerJob, error) {
// if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil {
diff --git a/coderd/database/dbauthz/dbauthz_test.go b/coderd/database/dbauthz/dbauthz_test.go
index e99bc37271c16..f7c438f4a55e9 100644
--- a/coderd/database/dbauthz/dbauthz_test.go
+++ b/coderd/database/dbauthz/dbauthz_test.go
@@ -859,6 +859,78 @@ func (s *MethodTestSuite) TestOrganization() {
rbac.ResourceAssignOrgRole.InOrg(o.ID), policy.ActionAssign,
rbac.ResourceOrganizationMember.InOrg(o.ID).WithID(u.ID), policy.ActionCreate)
}))
+ s.Run("InsertPreset", s.Subtest(func(db database.Store, check *expects) {
+ org := dbgen.Organization(s.T(), db, database.Organization{})
+ user := dbgen.User(s.T(), db, database.User{})
+ template := dbgen.Template(s.T(), db, database.Template{
+ CreatedBy: user.ID,
+ OrganizationID: org.ID,
+ })
+ templateVersion := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
+ TemplateID: uuid.NullUUID{UUID: template.ID, Valid: true},
+ OrganizationID: org.ID,
+ CreatedBy: user.ID,
+ })
+ workspace := dbgen.Workspace(s.T(), db, database.WorkspaceTable{
+ OrganizationID: org.ID,
+ OwnerID: user.ID,
+ TemplateID: template.ID,
+ })
+ job := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{
+ OrganizationID: org.ID,
+ })
+ workspaceBuild := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{
+ WorkspaceID: workspace.ID,
+ TemplateVersionID: templateVersion.ID,
+ InitiatorID: user.ID,
+ JobID: job.ID,
+ })
+ insertPresetParams := database.InsertPresetParams{
+ ID: uuid.New(),
+ TemplateVersionID: workspaceBuild.TemplateVersionID,
+ Name: "test",
+ }
+ check.Args(insertPresetParams).Asserts(rbac.ResourceTemplate, policy.ActionUpdate)
+ }))
+ s.Run("InsertPresetParameters", s.Subtest(func(db database.Store, check *expects) {
+ org := dbgen.Organization(s.T(), db, database.Organization{})
+ user := dbgen.User(s.T(), db, database.User{})
+ template := dbgen.Template(s.T(), db, database.Template{
+ CreatedBy: user.ID,
+ OrganizationID: org.ID,
+ })
+ templateVersion := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
+ TemplateID: uuid.NullUUID{UUID: template.ID, Valid: true},
+ OrganizationID: org.ID,
+ CreatedBy: user.ID,
+ })
+ workspace := dbgen.Workspace(s.T(), db, database.WorkspaceTable{
+ OrganizationID: org.ID,
+ OwnerID: user.ID,
+ TemplateID: template.ID,
+ })
+ job := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{
+ OrganizationID: org.ID,
+ })
+ workspaceBuild := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{
+ WorkspaceID: workspace.ID,
+ TemplateVersionID: templateVersion.ID,
+ InitiatorID: user.ID,
+ JobID: job.ID,
+ })
+ insertPresetParams := database.InsertPresetParams{
+ TemplateVersionID: workspaceBuild.TemplateVersionID,
+ Name: "test",
+ }
+ preset, err := db.InsertPreset(context.Background(), insertPresetParams)
+ require.NoError(s.T(), err)
+ insertPresetParametersParams := database.InsertPresetParametersParams{
+ TemplateVersionPresetID: preset.ID,
+ Names: []string{"test"},
+ Values: []string{"test"},
+ }
+ check.Args(insertPresetParametersParams).Asserts(rbac.ResourceTemplate, policy.ActionUpdate)
+ }))
s.Run("DeleteOrganizationMember", s.Subtest(func(db database.Store, check *expects) {
o := dbgen.Organization(s.T(), db, database.Organization{})
u := dbgen.User(s.T(), db, database.User{})
@@ -3695,6 +3767,98 @@ func (s *MethodTestSuite) TestSystemFunctions() {
ErrorsWithInMemDB(sql.ErrNoRows).
Returns([]database.ParameterSchema{})
}))
+ s.Run("GetPresetByWorkspaceBuildID", s.Subtest(func(db database.Store, check *expects) {
+ org := dbgen.Organization(s.T(), db, database.Organization{})
+ user := dbgen.User(s.T(), db, database.User{})
+ template := dbgen.Template(s.T(), db, database.Template{
+ CreatedBy: user.ID,
+ OrganizationID: org.ID,
+ })
+ templateVersion := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
+ TemplateID: uuid.NullUUID{UUID: template.ID, Valid: true},
+ OrganizationID: org.ID,
+ CreatedBy: user.ID,
+ })
+ preset, err := db.InsertPreset(context.Background(), database.InsertPresetParams{
+ TemplateVersionID: templateVersion.ID,
+ Name: "test",
+ })
+ require.NoError(s.T(), err)
+ workspace := dbgen.Workspace(s.T(), db, database.WorkspaceTable{
+ OrganizationID: org.ID,
+ OwnerID: user.ID,
+ TemplateID: template.ID,
+ })
+ job := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{
+ OrganizationID: org.ID,
+ })
+ workspaceBuild := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{
+ WorkspaceID: workspace.ID,
+ TemplateVersionID: templateVersion.ID,
+ TemplateVersionPresetID: uuid.NullUUID{UUID: preset.ID, Valid: true},
+ InitiatorID: user.ID,
+ JobID: job.ID,
+ })
+ _, err = db.GetPresetByWorkspaceBuildID(context.Background(), workspaceBuild.ID)
+ require.NoError(s.T(), err)
+ check.Args(workspaceBuild.ID).Asserts(rbac.ResourceTemplate, policy.ActionRead)
+ }))
+ s.Run("GetPresetParametersByTemplateVersionID", s.Subtest(func(db database.Store, check *expects) {
+ ctx := context.Background()
+ org := dbgen.Organization(s.T(), db, database.Organization{})
+ user := dbgen.User(s.T(), db, database.User{})
+ template := dbgen.Template(s.T(), db, database.Template{
+ CreatedBy: user.ID,
+ OrganizationID: org.ID,
+ })
+ templateVersion := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
+ TemplateID: uuid.NullUUID{UUID: template.ID, Valid: true},
+ OrganizationID: org.ID,
+ CreatedBy: user.ID,
+ })
+ preset, err := db.InsertPreset(ctx, database.InsertPresetParams{
+ ID: uuid.New(),
+ TemplateVersionID: templateVersion.ID,
+ Name: "test",
+ })
+ require.NoError(s.T(), err)
+ _, err = db.InsertPresetParameters(ctx, database.InsertPresetParametersParams{
+ ID: uuid.New(),
+ TemplateVersionPresetID: preset.ID,
+ Names: []string{"test"},
+ Values: []string{"test"},
+ })
+ require.NoError(s.T(), err)
+ presetParameters, err := db.GetPresetParametersByTemplateVersionID(ctx, templateVersion.ID)
+ require.NoError(s.T(), err)
+
+ check.Args(templateVersion.ID).Asserts(template.RBACObject(), policy.ActionRead).Returns(presetParameters)
+ }))
+ s.Run("GetPresetsByTemplateVersionID", s.Subtest(func(db database.Store, check *expects) {
+ ctx := context.Background()
+ org := dbgen.Organization(s.T(), db, database.Organization{})
+ user := dbgen.User(s.T(), db, database.User{})
+ template := dbgen.Template(s.T(), db, database.Template{
+ CreatedBy: user.ID,
+ OrganizationID: org.ID,
+ })
+ templateVersion := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
+ TemplateID: uuid.NullUUID{UUID: template.ID, Valid: true},
+ OrganizationID: org.ID,
+ CreatedBy: user.ID,
+ })
+
+ _, err := db.InsertPreset(ctx, database.InsertPresetParams{
+ TemplateVersionID: templateVersion.ID,
+ Name: "test",
+ })
+ require.NoError(s.T(), err)
+
+ presets, err := db.GetPresetsByTemplateVersionID(ctx, templateVersion.ID)
+ require.NoError(s.T(), err)
+
+ check.Args(templateVersion.ID).Asserts(template.RBACObject(), policy.ActionRead).Returns(presets)
+ }))
s.Run("GetWorkspaceAppsByAgentIDs", s.Subtest(func(db database.Store, check *expects) {
dbtestutil.DisableForeignKeysAndTriggers(s.T(), db)
aWs := dbgen.Workspace(s.T(), db, database.WorkspaceTable{})
diff --git a/coderd/database/dbgen/dbgen.go b/coderd/database/dbgen/dbgen.go
index 79730f9e04b06..cfd360f740183 100644
--- a/coderd/database/dbgen/dbgen.go
+++ b/coderd/database/dbgen/dbgen.go
@@ -314,6 +314,10 @@ func WorkspaceBuild(t testing.TB, db database.Store, orig database.WorkspaceBuil
Deadline: takeFirst(orig.Deadline, dbtime.Now().Add(time.Hour)),
MaxDeadline: takeFirst(orig.MaxDeadline, time.Time{}),
Reason: takeFirst(orig.Reason, database.BuildReasonInitiator),
+ TemplateVersionPresetID: takeFirst(orig.TemplateVersionPresetID, uuid.NullUUID{
+ UUID: uuid.UUID{},
+ Valid: false,
+ }),
})
if err != nil {
return err
diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go
index 007362eab6196..8d68054a49444 100644
--- a/coderd/database/dbmem/dbmem.go
+++ b/coderd/database/dbmem/dbmem.go
@@ -90,6 +90,8 @@ func New() database.Store {
runtimeConfig: map[string]string{},
userStatusChanges: make([]database.UserStatusChange, 0),
telemetryItems: make([]database.TelemetryItem, 0),
+ presets: make([]database.TemplateVersionPreset, 0),
+ presetParameters: make([]database.TemplateVersionPresetParameter, 0),
},
}
// Always start with a default org. Matching migration 198.
@@ -262,6 +264,8 @@ type data struct {
defaultProxyIconURL string
userStatusChanges []database.UserStatusChange
telemetryItems []database.TelemetryItem
+ presets []database.TemplateVersionPreset
+ presetParameters []database.TemplateVersionPresetParameter
}
func tryPercentile(fs []float64, p float64) float64 {
@@ -3776,6 +3780,61 @@ func (q *FakeQuerier) GetParameterSchemasByJobID(_ context.Context, jobID uuid.U
return parameters, nil
}
+func (q *FakeQuerier) GetPresetByWorkspaceBuildID(_ context.Context, workspaceBuildID uuid.UUID) (database.TemplateVersionPreset, error) {
+ q.mutex.RLock()
+ defer q.mutex.RUnlock()
+
+ for _, workspaceBuild := range q.workspaceBuilds {
+ if workspaceBuild.ID != workspaceBuildID {
+ continue
+ }
+ for _, preset := range q.presets {
+ if preset.TemplateVersionID == workspaceBuild.TemplateVersionID {
+ return preset, nil
+ }
+ }
+ }
+ return database.TemplateVersionPreset{}, sql.ErrNoRows
+}
+
+func (q *FakeQuerier) GetPresetParametersByTemplateVersionID(_ context.Context, templateVersionID uuid.UUID) ([]database.TemplateVersionPresetParameter, error) {
+ q.mutex.RLock()
+ defer q.mutex.RUnlock()
+
+ presets := make([]database.TemplateVersionPreset, 0)
+ parameters := make([]database.TemplateVersionPresetParameter, 0)
+ for _, preset := range q.presets {
+ if preset.TemplateVersionID != templateVersionID {
+ continue
+ }
+ presets = append(presets, preset)
+ }
+ for _, parameter := range q.presetParameters {
+ for _, preset := range presets {
+ if parameter.TemplateVersionPresetID != preset.ID {
+ continue
+ }
+ parameters = append(parameters, parameter)
+ break
+ }
+ }
+
+ return parameters, nil
+}
+
+func (q *FakeQuerier) GetPresetsByTemplateVersionID(_ context.Context, templateVersionID uuid.UUID) ([]database.TemplateVersionPreset, error) {
+ q.mutex.RLock()
+ defer q.mutex.RUnlock()
+
+ presets := make([]database.TemplateVersionPreset, 0)
+ for _, preset := range q.presets {
+ if preset.TemplateVersionID == templateVersionID {
+ presets = append(presets, preset)
+ }
+ }
+ return presets, nil
+}
+
func (q *FakeQuerier) GetPreviousTemplateVersion(_ context.Context, arg database.GetPreviousTemplateVersionParams) (database.TemplateVersion, error) {
if err := validateDatabaseType(arg); err != nil {
return database.TemplateVersion{}, err
@@ -8081,6 +8140,49 @@ func (q *FakeQuerier) InsertOrganizationMember(_ context.Context, arg database.I
return organizationMember, nil
}
+func (q *FakeQuerier) InsertPreset(_ context.Context, arg database.InsertPresetParams) (database.TemplateVersionPreset, error) {
+ err := validateDatabaseType(arg)
+ if err != nil {
+ return database.TemplateVersionPreset{}, err
+ }
+
+ q.mutex.Lock()
+ defer q.mutex.Unlock()
+
+ preset := database.TemplateVersionPreset{
+ ID: uuid.New(),
+ TemplateVersionID: arg.TemplateVersionID,
+ Name: arg.Name,
+ CreatedAt: arg.CreatedAt,
+ }
+ q.presets = append(q.presets, preset)
+ return preset, nil
+}
+
+func (q *FakeQuerier) InsertPresetParameters(_ context.Context, arg database.InsertPresetParametersParams) ([]database.TemplateVersionPresetParameter, error) {
+ err := validateDatabaseType(arg)
+ if err != nil {
+ return nil, err
+ }
+
+ q.mutex.Lock()
+ defer q.mutex.Unlock()
+
+ presetParameters := make([]database.TemplateVersionPresetParameter, 0, len(arg.Names))
+ for i, v := range arg.Names {
+ presetParameter := database.TemplateVersionPresetParameter{
+ ID: uuid.New(),
+ TemplateVersionPresetID: arg.TemplateVersionPresetID,
+ Name: v,
+ Value: arg.Values[i],
+ }
+ presetParameters = append(presetParameters, presetParameter)
+ q.presetParameters = append(q.presetParameters, presetParameter)
+ }
+
+ return presetParameters, nil
+}
+
func (q *FakeQuerier) InsertProvisionerJob(_ context.Context, arg database.InsertProvisionerJobParams) (database.ProvisionerJob, error) {
if err := validateDatabaseType(arg); err != nil {
return database.ProvisionerJob{}, err
diff --git a/coderd/database/dbmetrics/querymetrics.go b/coderd/database/dbmetrics/querymetrics.go
index 8a61fe9ac9a28..fc84f556aabfb 100644
--- a/coderd/database/dbmetrics/querymetrics.go
+++ b/coderd/database/dbmetrics/querymetrics.go
@@ -980,6 +980,27 @@ func (m queryMetricsStore) GetParameterSchemasByJobID(ctx context.Context, jobID
return schemas, err
}
+func (m queryMetricsStore) GetPresetByWorkspaceBuildID(ctx context.Context, workspaceBuildID uuid.UUID) (database.TemplateVersionPreset, error) {
+ start := time.Now()
+ r0, r1 := m.s.GetPresetByWorkspaceBuildID(ctx, workspaceBuildID)
+ m.queryLatencies.WithLabelValues("GetPresetByWorkspaceBuildID").Observe(time.Since(start).Seconds())
+ return r0, r1
+}
+
+func (m queryMetricsStore) GetPresetParametersByTemplateVersionID(ctx context.Context, templateVersionID uuid.UUID) ([]database.TemplateVersionPresetParameter, error) {
+ start := time.Now()
+ r0, r1 := m.s.GetPresetParametersByTemplateVersionID(ctx, templateVersionID)
+ m.queryLatencies.WithLabelValues("GetPresetParametersByTemplateVersionID").Observe(time.Since(start).Seconds())
+ return r0, r1
+}
+
+func (m queryMetricsStore) GetPresetsByTemplateVersionID(ctx context.Context, templateVersionID uuid.UUID) ([]database.TemplateVersionPreset, error) {
+ start := time.Now()
+ r0, r1 := m.s.GetPresetsByTemplateVersionID(ctx, templateVersionID)
+ m.queryLatencies.WithLabelValues("GetPresetsByTemplateVersionID").Observe(time.Since(start).Seconds())
+ return r0, r1
+}
+
func (m queryMetricsStore) GetPreviousTemplateVersion(ctx context.Context, arg database.GetPreviousTemplateVersionParams) (database.TemplateVersion, error) {
start := time.Now()
version, err := m.s.GetPreviousTemplateVersion(ctx, arg)
@@ -1911,6 +1932,20 @@ func (m queryMetricsStore) InsertOrganizationMember(ctx context.Context, arg dat
return member, err
}
+func (m queryMetricsStore) InsertPreset(ctx context.Context, arg database.InsertPresetParams) (database.TemplateVersionPreset, error) {
+ start := time.Now()
+ r0, r1 := m.s.InsertPreset(ctx, arg)
+ m.queryLatencies.WithLabelValues("InsertPreset").Observe(time.Since(start).Seconds())
+ return r0, r1
+}
+
+func (m queryMetricsStore) InsertPresetParameters(ctx context.Context, arg database.InsertPresetParametersParams) ([]database.TemplateVersionPresetParameter, error) {
+ start := time.Now()
+ r0, r1 := m.s.InsertPresetParameters(ctx, arg)
+ m.queryLatencies.WithLabelValues("InsertPresetParameters").Observe(time.Since(start).Seconds())
+ return r0, r1
+}
+
func (m queryMetricsStore) InsertProvisionerJob(ctx context.Context, arg database.InsertProvisionerJobParams) (database.ProvisionerJob, error) {
start := time.Now()
job, err := m.s.InsertProvisionerJob(ctx, arg)
diff --git a/coderd/database/dbmock/dbmock.go b/coderd/database/dbmock/dbmock.go
index 3427992ed8cdc..d51631316a3cd 100644
--- a/coderd/database/dbmock/dbmock.go
+++ b/coderd/database/dbmock/dbmock.go
@@ -2016,6 +2016,51 @@ func (mr *MockStoreMockRecorder) GetParameterSchemasByJobID(ctx, jobID any) *gom
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParameterSchemasByJobID", reflect.TypeOf((*MockStore)(nil).GetParameterSchemasByJobID), ctx, jobID)
}
+// GetPresetByWorkspaceBuildID mocks base method.
+func (m *MockStore) GetPresetByWorkspaceBuildID(ctx context.Context, workspaceBuildID uuid.UUID) (database.TemplateVersionPreset, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "GetPresetByWorkspaceBuildID", ctx, workspaceBuildID)
+ ret0, _ := ret[0].(database.TemplateVersionPreset)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// GetPresetByWorkspaceBuildID indicates an expected call of GetPresetByWorkspaceBuildID.
+func (mr *MockStoreMockRecorder) GetPresetByWorkspaceBuildID(ctx, workspaceBuildID any) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPresetByWorkspaceBuildID", reflect.TypeOf((*MockStore)(nil).GetPresetByWorkspaceBuildID), ctx, workspaceBuildID)
+}
+
+// GetPresetParametersByTemplateVersionID mocks base method.
+func (m *MockStore) GetPresetParametersByTemplateVersionID(ctx context.Context, templateVersionID uuid.UUID) ([]database.TemplateVersionPresetParameter, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "GetPresetParametersByTemplateVersionID", ctx, templateVersionID)
+ ret0, _ := ret[0].([]database.TemplateVersionPresetParameter)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// GetPresetParametersByTemplateVersionID indicates an expected call of GetPresetParametersByTemplateVersionID.
+func (mr *MockStoreMockRecorder) GetPresetParametersByTemplateVersionID(ctx, templateVersionID any) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPresetParametersByTemplateVersionID", reflect.TypeOf((*MockStore)(nil).GetPresetParametersByTemplateVersionID), ctx, templateVersionID)
+}
+
+// GetPresetsByTemplateVersionID mocks base method.
+func (m *MockStore) GetPresetsByTemplateVersionID(ctx context.Context, templateVersionID uuid.UUID) ([]database.TemplateVersionPreset, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "GetPresetsByTemplateVersionID", ctx, templateVersionID)
+ ret0, _ := ret[0].([]database.TemplateVersionPreset)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// GetPresetsByTemplateVersionID indicates an expected call of GetPresetsByTemplateVersionID.
+func (mr *MockStoreMockRecorder) GetPresetsByTemplateVersionID(ctx, templateVersionID any) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPresetsByTemplateVersionID", reflect.TypeOf((*MockStore)(nil).GetPresetsByTemplateVersionID), ctx, templateVersionID)
+}
+
// GetPreviousTemplateVersion mocks base method.
func (m *MockStore) GetPreviousTemplateVersion(ctx context.Context, arg database.GetPreviousTemplateVersionParams) (database.TemplateVersion, error) {
m.ctrl.T.Helper()
@@ -4051,6 +4096,36 @@ func (mr *MockStoreMockRecorder) InsertOrganizationMember(ctx, arg any) *gomock.
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertOrganizationMember", reflect.TypeOf((*MockStore)(nil).InsertOrganizationMember), ctx, arg)
}
+// InsertPreset mocks base method.
+func (m *MockStore) InsertPreset(ctx context.Context, arg database.InsertPresetParams) (database.TemplateVersionPreset, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "InsertPreset", ctx, arg)
+ ret0, _ := ret[0].(database.TemplateVersionPreset)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// InsertPreset indicates an expected call of InsertPreset.
+func (mr *MockStoreMockRecorder) InsertPreset(ctx, arg any) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertPreset", reflect.TypeOf((*MockStore)(nil).InsertPreset), ctx, arg)
+}
+
+// InsertPresetParameters mocks base method.
+func (m *MockStore) InsertPresetParameters(ctx context.Context, arg database.InsertPresetParametersParams) ([]database.TemplateVersionPresetParameter, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "InsertPresetParameters", ctx, arg)
+ ret0, _ := ret[0].([]database.TemplateVersionPresetParameter)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// InsertPresetParameters indicates an expected call of InsertPresetParameters.
+func (mr *MockStoreMockRecorder) InsertPresetParameters(ctx, arg any) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertPresetParameters", reflect.TypeOf((*MockStore)(nil).InsertPresetParameters), ctx, arg)
+}
+
// InsertProvisionerJob mocks base method.
func (m *MockStore) InsertProvisionerJob(ctx context.Context, arg database.InsertProvisionerJobParams) (database.ProvisionerJob, error) {
m.ctrl.T.Helper()
diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql
index d3d12b5075e7e..7bd2052a2276f 100644
--- a/coderd/database/dump.sql
+++ b/coderd/database/dump.sql
@@ -1265,6 +1265,20 @@ COMMENT ON COLUMN template_version_parameters.display_order IS 'Specifies the or
COMMENT ON COLUMN template_version_parameters.ephemeral IS 'The value of an ephemeral parameter will not be preserved between consecutive workspace builds.';
+CREATE TABLE template_version_preset_parameters (
+ id uuid NOT NULL,
+ template_version_preset_id uuid NOT NULL,
+ name text NOT NULL,
+ value text NOT NULL
+);
+
+CREATE TABLE template_version_presets (
+ id uuid NOT NULL,
+ template_version_id uuid NOT NULL,
+ name text NOT NULL,
+ created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
+);
+
CREATE TABLE template_version_variables (
template_version_id uuid NOT NULL,
name text NOT NULL,
@@ -1729,7 +1743,8 @@ CREATE TABLE workspace_builds (
deadline timestamp with time zone DEFAULT '0001-01-01 00:00:00+00'::timestamp with time zone NOT NULL,
reason build_reason DEFAULT 'initiator'::build_reason NOT NULL,
daily_cost integer DEFAULT 0 NOT NULL,
- max_deadline timestamp with time zone DEFAULT '0001-01-01 00:00:00+00'::timestamp with time zone NOT NULL
+ max_deadline timestamp with time zone DEFAULT '0001-01-01 00:00:00+00'::timestamp with time zone NOT NULL,
+ template_version_preset_id uuid
);
CREATE VIEW workspace_build_with_user AS
@@ -1747,6 +1762,7 @@ CREATE VIEW workspace_build_with_user AS
workspace_builds.reason,
workspace_builds.daily_cost,
workspace_builds.max_deadline,
+ workspace_builds.template_version_preset_id,
COALESCE(visible_users.avatar_url, ''::text) AS initiator_by_avatar_url,
COALESCE(visible_users.username, ''::text) AS initiator_by_username
FROM (workspace_builds
@@ -2057,6 +2073,12 @@ ALTER TABLE ONLY template_usage_stats
ALTER TABLE ONLY template_version_parameters
ADD CONSTRAINT template_version_parameters_template_version_id_name_key UNIQUE (template_version_id, name);
+ALTER TABLE ONLY template_version_preset_parameters
+ ADD CONSTRAINT template_version_preset_parameters_pkey PRIMARY KEY (id);
+
+ALTER TABLE ONLY template_version_presets
+ ADD CONSTRAINT template_version_presets_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY template_version_variables
ADD CONSTRAINT template_version_variables_template_version_id_name_key UNIQUE (template_version_id, name);
@@ -2447,6 +2469,12 @@ ALTER TABLE ONLY tailnet_tunnels
ALTER TABLE ONLY template_version_parameters
ADD CONSTRAINT template_version_parameters_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
+ALTER TABLE ONLY template_version_preset_parameters
+ ADD CONSTRAINT template_version_preset_paramet_template_version_preset_id_fkey FOREIGN KEY (template_version_preset_id) REFERENCES template_version_presets(id) ON DELETE CASCADE;
+
+ALTER TABLE ONLY template_version_presets
+ ADD CONSTRAINT template_version_presets_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY template_version_variables
ADD CONSTRAINT template_version_variables_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
@@ -2531,6 +2559,9 @@ ALTER TABLE ONLY workspace_builds
ALTER TABLE ONLY workspace_builds
ADD CONSTRAINT workspace_builds_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
+ALTER TABLE ONLY workspace_builds
+ ADD CONSTRAINT workspace_builds_template_version_preset_id_fkey FOREIGN KEY (template_version_preset_id) REFERENCES template_version_presets(id) ON DELETE SET NULL;
+
ALTER TABLE ONLY workspace_builds
ADD CONSTRAINT workspace_builds_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE;
diff --git a/coderd/database/foreign_key_constraint.go b/coderd/database/foreign_key_constraint.go
index 275b48ed575c1..66c379a749e01 100644
--- a/coderd/database/foreign_key_constraint.go
+++ b/coderd/database/foreign_key_constraint.go
@@ -6,73 +6,76 @@ type ForeignKeyConstraint string
// ForeignKeyConstraint enums.
const (
- ForeignKeyAPIKeysUserIDUUID ForeignKeyConstraint = "api_keys_user_id_uuid_fkey" // ALTER TABLE ONLY api_keys ADD CONSTRAINT api_keys_user_id_uuid_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
- ForeignKeyCryptoKeysSecretKeyID ForeignKeyConstraint = "crypto_keys_secret_key_id_fkey" // ALTER TABLE ONLY crypto_keys ADD CONSTRAINT crypto_keys_secret_key_id_fkey FOREIGN KEY (secret_key_id) REFERENCES dbcrypt_keys(active_key_digest);
- ForeignKeyGitAuthLinksOauthAccessTokenKeyID ForeignKeyConstraint = "git_auth_links_oauth_access_token_key_id_fkey" // ALTER TABLE ONLY external_auth_links ADD CONSTRAINT git_auth_links_oauth_access_token_key_id_fkey FOREIGN KEY (oauth_access_token_key_id) REFERENCES dbcrypt_keys(active_key_digest);
- ForeignKeyGitAuthLinksOauthRefreshTokenKeyID ForeignKeyConstraint = "git_auth_links_oauth_refresh_token_key_id_fkey" // ALTER TABLE ONLY external_auth_links ADD CONSTRAINT git_auth_links_oauth_refresh_token_key_id_fkey FOREIGN KEY (oauth_refresh_token_key_id) REFERENCES dbcrypt_keys(active_key_digest);
- ForeignKeyGitSSHKeysUserID ForeignKeyConstraint = "gitsshkeys_user_id_fkey" // ALTER TABLE ONLY gitsshkeys ADD CONSTRAINT gitsshkeys_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id);
- ForeignKeyGroupMembersGroupID ForeignKeyConstraint = "group_members_group_id_fkey" // ALTER TABLE ONLY group_members ADD CONSTRAINT group_members_group_id_fkey FOREIGN KEY (group_id) REFERENCES groups(id) ON DELETE CASCADE;
- ForeignKeyGroupMembersUserID ForeignKeyConstraint = "group_members_user_id_fkey" // ALTER TABLE ONLY group_members ADD CONSTRAINT group_members_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
- ForeignKeyGroupsOrganizationID ForeignKeyConstraint = "groups_organization_id_fkey" // ALTER TABLE ONLY groups ADD CONSTRAINT groups_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
- ForeignKeyJfrogXrayScansAgentID ForeignKeyConstraint = "jfrog_xray_scans_agent_id_fkey" // ALTER TABLE ONLY jfrog_xray_scans ADD CONSTRAINT jfrog_xray_scans_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
- ForeignKeyJfrogXrayScansWorkspaceID ForeignKeyConstraint = "jfrog_xray_scans_workspace_id_fkey" // ALTER TABLE ONLY jfrog_xray_scans ADD CONSTRAINT jfrog_xray_scans_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE;
- ForeignKeyNotificationMessagesNotificationTemplateID ForeignKeyConstraint = "notification_messages_notification_template_id_fkey" // ALTER TABLE ONLY notification_messages ADD CONSTRAINT notification_messages_notification_template_id_fkey FOREIGN KEY (notification_template_id) REFERENCES notification_templates(id) ON DELETE CASCADE;
- ForeignKeyNotificationMessagesUserID ForeignKeyConstraint = "notification_messages_user_id_fkey" // ALTER TABLE ONLY notification_messages ADD CONSTRAINT notification_messages_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
- ForeignKeyNotificationPreferencesNotificationTemplateID ForeignKeyConstraint = "notification_preferences_notification_template_id_fkey" // ALTER TABLE ONLY notification_preferences ADD CONSTRAINT notification_preferences_notification_template_id_fkey FOREIGN KEY (notification_template_id) REFERENCES notification_templates(id) ON DELETE CASCADE;
- ForeignKeyNotificationPreferencesUserID ForeignKeyConstraint = "notification_preferences_user_id_fkey" // ALTER TABLE ONLY notification_preferences ADD CONSTRAINT notification_preferences_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
- ForeignKeyOauth2ProviderAppCodesAppID ForeignKeyConstraint = "oauth2_provider_app_codes_app_id_fkey" // ALTER TABLE ONLY oauth2_provider_app_codes ADD CONSTRAINT oauth2_provider_app_codes_app_id_fkey FOREIGN KEY (app_id) REFERENCES oauth2_provider_apps(id) ON DELETE CASCADE;
- ForeignKeyOauth2ProviderAppCodesUserID ForeignKeyConstraint = "oauth2_provider_app_codes_user_id_fkey" // ALTER TABLE ONLY oauth2_provider_app_codes ADD CONSTRAINT oauth2_provider_app_codes_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
- ForeignKeyOauth2ProviderAppSecretsAppID ForeignKeyConstraint = "oauth2_provider_app_secrets_app_id_fkey" // ALTER TABLE ONLY oauth2_provider_app_secrets ADD CONSTRAINT oauth2_provider_app_secrets_app_id_fkey FOREIGN KEY (app_id) REFERENCES oauth2_provider_apps(id) ON DELETE CASCADE;
- ForeignKeyOauth2ProviderAppTokensAPIKeyID ForeignKeyConstraint = "oauth2_provider_app_tokens_api_key_id_fkey" // ALTER TABLE ONLY oauth2_provider_app_tokens ADD CONSTRAINT oauth2_provider_app_tokens_api_key_id_fkey FOREIGN KEY (api_key_id) REFERENCES api_keys(id) ON DELETE CASCADE;
- ForeignKeyOauth2ProviderAppTokensAppSecretID ForeignKeyConstraint = "oauth2_provider_app_tokens_app_secret_id_fkey" // ALTER TABLE ONLY oauth2_provider_app_tokens ADD CONSTRAINT oauth2_provider_app_tokens_app_secret_id_fkey FOREIGN KEY (app_secret_id) REFERENCES oauth2_provider_app_secrets(id) ON DELETE CASCADE;
- ForeignKeyOrganizationMembersOrganizationIDUUID ForeignKeyConstraint = "organization_members_organization_id_uuid_fkey" // ALTER TABLE ONLY organization_members ADD CONSTRAINT organization_members_organization_id_uuid_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
- ForeignKeyOrganizationMembersUserIDUUID ForeignKeyConstraint = "organization_members_user_id_uuid_fkey" // ALTER TABLE ONLY organization_members ADD CONSTRAINT organization_members_user_id_uuid_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
- ForeignKeyParameterSchemasJobID ForeignKeyConstraint = "parameter_schemas_job_id_fkey" // ALTER TABLE ONLY parameter_schemas ADD CONSTRAINT parameter_schemas_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
- ForeignKeyProvisionerDaemonsKeyID ForeignKeyConstraint = "provisioner_daemons_key_id_fkey" // ALTER TABLE ONLY provisioner_daemons ADD CONSTRAINT provisioner_daemons_key_id_fkey FOREIGN KEY (key_id) REFERENCES provisioner_keys(id) ON DELETE CASCADE;
- ForeignKeyProvisionerDaemonsOrganizationID ForeignKeyConstraint = "provisioner_daemons_organization_id_fkey" // ALTER TABLE ONLY provisioner_daemons ADD CONSTRAINT provisioner_daemons_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
- ForeignKeyProvisionerJobLogsJobID ForeignKeyConstraint = "provisioner_job_logs_job_id_fkey" // ALTER TABLE ONLY provisioner_job_logs ADD CONSTRAINT provisioner_job_logs_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
- ForeignKeyProvisionerJobTimingsJobID ForeignKeyConstraint = "provisioner_job_timings_job_id_fkey" // ALTER TABLE ONLY provisioner_job_timings ADD CONSTRAINT provisioner_job_timings_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
- ForeignKeyProvisionerJobsOrganizationID ForeignKeyConstraint = "provisioner_jobs_organization_id_fkey" // ALTER TABLE ONLY provisioner_jobs ADD CONSTRAINT provisioner_jobs_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
- ForeignKeyProvisionerKeysOrganizationID ForeignKeyConstraint = "provisioner_keys_organization_id_fkey" // ALTER TABLE ONLY provisioner_keys ADD CONSTRAINT provisioner_keys_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
- ForeignKeyTailnetAgentsCoordinatorID ForeignKeyConstraint = "tailnet_agents_coordinator_id_fkey" // ALTER TABLE ONLY tailnet_agents ADD CONSTRAINT tailnet_agents_coordinator_id_fkey FOREIGN KEY (coordinator_id) REFERENCES tailnet_coordinators(id) ON DELETE CASCADE;
- ForeignKeyTailnetClientSubscriptionsCoordinatorID ForeignKeyConstraint = "tailnet_client_subscriptions_coordinator_id_fkey" // ALTER TABLE ONLY tailnet_client_subscriptions ADD CONSTRAINT tailnet_client_subscriptions_coordinator_id_fkey FOREIGN KEY (coordinator_id) REFERENCES tailnet_coordinators(id) ON DELETE CASCADE;
- ForeignKeyTailnetClientsCoordinatorID ForeignKeyConstraint = "tailnet_clients_coordinator_id_fkey" // ALTER TABLE ONLY tailnet_clients ADD CONSTRAINT tailnet_clients_coordinator_id_fkey FOREIGN KEY (coordinator_id) REFERENCES tailnet_coordinators(id) ON DELETE CASCADE;
- ForeignKeyTailnetPeersCoordinatorID ForeignKeyConstraint = "tailnet_peers_coordinator_id_fkey" // ALTER TABLE ONLY tailnet_peers ADD CONSTRAINT tailnet_peers_coordinator_id_fkey FOREIGN KEY (coordinator_id) REFERENCES tailnet_coordinators(id) ON DELETE CASCADE;
- ForeignKeyTailnetTunnelsCoordinatorID ForeignKeyConstraint = "tailnet_tunnels_coordinator_id_fkey" // ALTER TABLE ONLY tailnet_tunnels ADD CONSTRAINT tailnet_tunnels_coordinator_id_fkey FOREIGN KEY (coordinator_id) REFERENCES tailnet_coordinators(id) ON DELETE CASCADE;
- ForeignKeyTemplateVersionParametersTemplateVersionID ForeignKeyConstraint = "template_version_parameters_template_version_id_fkey" // ALTER TABLE ONLY template_version_parameters ADD CONSTRAINT template_version_parameters_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
- ForeignKeyTemplateVersionVariablesTemplateVersionID ForeignKeyConstraint = "template_version_variables_template_version_id_fkey" // ALTER TABLE ONLY template_version_variables ADD CONSTRAINT template_version_variables_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
- ForeignKeyTemplateVersionWorkspaceTagsTemplateVersionID ForeignKeyConstraint = "template_version_workspace_tags_template_version_id_fkey" // ALTER TABLE ONLY template_version_workspace_tags ADD CONSTRAINT template_version_workspace_tags_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
- ForeignKeyTemplateVersionsCreatedBy ForeignKeyConstraint = "template_versions_created_by_fkey" // ALTER TABLE ONLY template_versions ADD CONSTRAINT template_versions_created_by_fkey FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE RESTRICT;
- ForeignKeyTemplateVersionsOrganizationID ForeignKeyConstraint = "template_versions_organization_id_fkey" // ALTER TABLE ONLY template_versions ADD CONSTRAINT template_versions_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
- ForeignKeyTemplateVersionsTemplateID ForeignKeyConstraint = "template_versions_template_id_fkey" // ALTER TABLE ONLY template_versions ADD CONSTRAINT template_versions_template_id_fkey FOREIGN KEY (template_id) REFERENCES templates(id) ON DELETE CASCADE;
- ForeignKeyTemplatesCreatedBy ForeignKeyConstraint = "templates_created_by_fkey" // ALTER TABLE ONLY templates ADD CONSTRAINT templates_created_by_fkey FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE RESTRICT;
- ForeignKeyTemplatesOrganizationID ForeignKeyConstraint = "templates_organization_id_fkey" // ALTER TABLE ONLY templates ADD CONSTRAINT templates_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
- ForeignKeyUserDeletedUserID ForeignKeyConstraint = "user_deleted_user_id_fkey" // ALTER TABLE ONLY user_deleted ADD CONSTRAINT user_deleted_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id);
- ForeignKeyUserLinksOauthAccessTokenKeyID ForeignKeyConstraint = "user_links_oauth_access_token_key_id_fkey" // ALTER TABLE ONLY user_links ADD CONSTRAINT user_links_oauth_access_token_key_id_fkey FOREIGN KEY (oauth_access_token_key_id) REFERENCES dbcrypt_keys(active_key_digest);
- ForeignKeyUserLinksOauthRefreshTokenKeyID ForeignKeyConstraint = "user_links_oauth_refresh_token_key_id_fkey" // ALTER TABLE ONLY user_links ADD CONSTRAINT user_links_oauth_refresh_token_key_id_fkey FOREIGN KEY (oauth_refresh_token_key_id) REFERENCES dbcrypt_keys(active_key_digest);
- ForeignKeyUserLinksUserID ForeignKeyConstraint = "user_links_user_id_fkey" // ALTER TABLE ONLY user_links ADD CONSTRAINT user_links_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
- ForeignKeyUserStatusChangesUserID ForeignKeyConstraint = "user_status_changes_user_id_fkey" // ALTER TABLE ONLY user_status_changes ADD CONSTRAINT user_status_changes_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id);
- ForeignKeyWorkspaceAgentLogSourcesWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_log_sources_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_log_sources ADD CONSTRAINT workspace_agent_log_sources_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
- ForeignKeyWorkspaceAgentMemoryResourceMonitorsAgentID ForeignKeyConstraint = "workspace_agent_memory_resource_monitors_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_memory_resource_monitors ADD CONSTRAINT workspace_agent_memory_resource_monitors_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
- ForeignKeyWorkspaceAgentMetadataWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_metadata_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_metadata ADD CONSTRAINT workspace_agent_metadata_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
- ForeignKeyWorkspaceAgentPortShareWorkspaceID ForeignKeyConstraint = "workspace_agent_port_share_workspace_id_fkey" // ALTER TABLE ONLY workspace_agent_port_share ADD CONSTRAINT workspace_agent_port_share_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE;
- ForeignKeyWorkspaceAgentScriptTimingsScriptID ForeignKeyConstraint = "workspace_agent_script_timings_script_id_fkey" // ALTER TABLE ONLY workspace_agent_script_timings ADD CONSTRAINT workspace_agent_script_timings_script_id_fkey FOREIGN KEY (script_id) REFERENCES workspace_agent_scripts(id) ON DELETE CASCADE;
- ForeignKeyWorkspaceAgentScriptsWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_scripts_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_scripts ADD CONSTRAINT workspace_agent_scripts_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
- ForeignKeyWorkspaceAgentStartupLogsAgentID ForeignKeyConstraint = "workspace_agent_startup_logs_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_logs ADD CONSTRAINT workspace_agent_startup_logs_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
- ForeignKeyWorkspaceAgentVolumeResourceMonitorsAgentID ForeignKeyConstraint = "workspace_agent_volume_resource_monitors_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_volume_resource_monitors ADD CONSTRAINT workspace_agent_volume_resource_monitors_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
- ForeignKeyWorkspaceAgentsResourceID ForeignKeyConstraint = "workspace_agents_resource_id_fkey" // ALTER TABLE ONLY workspace_agents ADD CONSTRAINT workspace_agents_resource_id_fkey FOREIGN KEY (resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE;
- ForeignKeyWorkspaceAppStatsAgentID ForeignKeyConstraint = "workspace_app_stats_agent_id_fkey" // ALTER TABLE ONLY workspace_app_stats ADD CONSTRAINT workspace_app_stats_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id);
- ForeignKeyWorkspaceAppStatsUserID ForeignKeyConstraint = "workspace_app_stats_user_id_fkey" // ALTER TABLE ONLY workspace_app_stats ADD CONSTRAINT workspace_app_stats_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id);
- ForeignKeyWorkspaceAppStatsWorkspaceID ForeignKeyConstraint = "workspace_app_stats_workspace_id_fkey" // ALTER TABLE ONLY workspace_app_stats ADD CONSTRAINT workspace_app_stats_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id);
- ForeignKeyWorkspaceAppsAgentID ForeignKeyConstraint = "workspace_apps_agent_id_fkey" // ALTER TABLE ONLY workspace_apps ADD CONSTRAINT workspace_apps_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
- ForeignKeyWorkspaceBuildParametersWorkspaceBuildID ForeignKeyConstraint = "workspace_build_parameters_workspace_build_id_fkey" // ALTER TABLE ONLY workspace_build_parameters ADD CONSTRAINT workspace_build_parameters_workspace_build_id_fkey FOREIGN KEY (workspace_build_id) REFERENCES workspace_builds(id) ON DELETE CASCADE;
- ForeignKeyWorkspaceBuildsJobID ForeignKeyConstraint = "workspace_builds_job_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
- ForeignKeyWorkspaceBuildsTemplateVersionID ForeignKeyConstraint = "workspace_builds_template_version_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
- ForeignKeyWorkspaceBuildsWorkspaceID ForeignKeyConstraint = "workspace_builds_workspace_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE;
- ForeignKeyWorkspaceModulesJobID ForeignKeyConstraint = "workspace_modules_job_id_fkey" // ALTER TABLE ONLY workspace_modules ADD CONSTRAINT workspace_modules_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
- ForeignKeyWorkspaceResourceMetadataWorkspaceResourceID ForeignKeyConstraint = "workspace_resource_metadata_workspace_resource_id_fkey" // ALTER TABLE ONLY workspace_resource_metadata ADD CONSTRAINT workspace_resource_metadata_workspace_resource_id_fkey FOREIGN KEY (workspace_resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE;
- ForeignKeyWorkspaceResourcesJobID ForeignKeyConstraint = "workspace_resources_job_id_fkey" // ALTER TABLE ONLY workspace_resources ADD CONSTRAINT workspace_resources_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
- ForeignKeyWorkspacesOrganizationID ForeignKeyConstraint = "workspaces_organization_id_fkey" // ALTER TABLE ONLY workspaces ADD CONSTRAINT workspaces_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE RESTRICT;
- ForeignKeyWorkspacesOwnerID ForeignKeyConstraint = "workspaces_owner_id_fkey" // ALTER TABLE ONLY workspaces ADD CONSTRAINT workspaces_owner_id_fkey FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE RESTRICT;
- ForeignKeyWorkspacesTemplateID ForeignKeyConstraint = "workspaces_template_id_fkey" // ALTER TABLE ONLY workspaces ADD CONSTRAINT workspaces_template_id_fkey FOREIGN KEY (template_id) REFERENCES templates(id) ON DELETE RESTRICT;
+ ForeignKeyAPIKeysUserIDUUID ForeignKeyConstraint = "api_keys_user_id_uuid_fkey" // ALTER TABLE ONLY api_keys ADD CONSTRAINT api_keys_user_id_uuid_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
+ ForeignKeyCryptoKeysSecretKeyID ForeignKeyConstraint = "crypto_keys_secret_key_id_fkey" // ALTER TABLE ONLY crypto_keys ADD CONSTRAINT crypto_keys_secret_key_id_fkey FOREIGN KEY (secret_key_id) REFERENCES dbcrypt_keys(active_key_digest);
+ ForeignKeyGitAuthLinksOauthAccessTokenKeyID ForeignKeyConstraint = "git_auth_links_oauth_access_token_key_id_fkey" // ALTER TABLE ONLY external_auth_links ADD CONSTRAINT git_auth_links_oauth_access_token_key_id_fkey FOREIGN KEY (oauth_access_token_key_id) REFERENCES dbcrypt_keys(active_key_digest);
+ ForeignKeyGitAuthLinksOauthRefreshTokenKeyID ForeignKeyConstraint = "git_auth_links_oauth_refresh_token_key_id_fkey" // ALTER TABLE ONLY external_auth_links ADD CONSTRAINT git_auth_links_oauth_refresh_token_key_id_fkey FOREIGN KEY (oauth_refresh_token_key_id) REFERENCES dbcrypt_keys(active_key_digest);
+ ForeignKeyGitSSHKeysUserID ForeignKeyConstraint = "gitsshkeys_user_id_fkey" // ALTER TABLE ONLY gitsshkeys ADD CONSTRAINT gitsshkeys_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id);
+ ForeignKeyGroupMembersGroupID ForeignKeyConstraint = "group_members_group_id_fkey" // ALTER TABLE ONLY group_members ADD CONSTRAINT group_members_group_id_fkey FOREIGN KEY (group_id) REFERENCES groups(id) ON DELETE CASCADE;
+ ForeignKeyGroupMembersUserID ForeignKeyConstraint = "group_members_user_id_fkey" // ALTER TABLE ONLY group_members ADD CONSTRAINT group_members_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
+ ForeignKeyGroupsOrganizationID ForeignKeyConstraint = "groups_organization_id_fkey" // ALTER TABLE ONLY groups ADD CONSTRAINT groups_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
+ ForeignKeyJfrogXrayScansAgentID ForeignKeyConstraint = "jfrog_xray_scans_agent_id_fkey" // ALTER TABLE ONLY jfrog_xray_scans ADD CONSTRAINT jfrog_xray_scans_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
+ ForeignKeyJfrogXrayScansWorkspaceID ForeignKeyConstraint = "jfrog_xray_scans_workspace_id_fkey" // ALTER TABLE ONLY jfrog_xray_scans ADD CONSTRAINT jfrog_xray_scans_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE;
+ ForeignKeyNotificationMessagesNotificationTemplateID ForeignKeyConstraint = "notification_messages_notification_template_id_fkey" // ALTER TABLE ONLY notification_messages ADD CONSTRAINT notification_messages_notification_template_id_fkey FOREIGN KEY (notification_template_id) REFERENCES notification_templates(id) ON DELETE CASCADE;
+ ForeignKeyNotificationMessagesUserID ForeignKeyConstraint = "notification_messages_user_id_fkey" // ALTER TABLE ONLY notification_messages ADD CONSTRAINT notification_messages_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
+ ForeignKeyNotificationPreferencesNotificationTemplateID ForeignKeyConstraint = "notification_preferences_notification_template_id_fkey" // ALTER TABLE ONLY notification_preferences ADD CONSTRAINT notification_preferences_notification_template_id_fkey FOREIGN KEY (notification_template_id) REFERENCES notification_templates(id) ON DELETE CASCADE;
+ ForeignKeyNotificationPreferencesUserID ForeignKeyConstraint = "notification_preferences_user_id_fkey" // ALTER TABLE ONLY notification_preferences ADD CONSTRAINT notification_preferences_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
+ ForeignKeyOauth2ProviderAppCodesAppID ForeignKeyConstraint = "oauth2_provider_app_codes_app_id_fkey" // ALTER TABLE ONLY oauth2_provider_app_codes ADD CONSTRAINT oauth2_provider_app_codes_app_id_fkey FOREIGN KEY (app_id) REFERENCES oauth2_provider_apps(id) ON DELETE CASCADE;
+ ForeignKeyOauth2ProviderAppCodesUserID ForeignKeyConstraint = "oauth2_provider_app_codes_user_id_fkey" // ALTER TABLE ONLY oauth2_provider_app_codes ADD CONSTRAINT oauth2_provider_app_codes_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
+ ForeignKeyOauth2ProviderAppSecretsAppID ForeignKeyConstraint = "oauth2_provider_app_secrets_app_id_fkey" // ALTER TABLE ONLY oauth2_provider_app_secrets ADD CONSTRAINT oauth2_provider_app_secrets_app_id_fkey FOREIGN KEY (app_id) REFERENCES oauth2_provider_apps(id) ON DELETE CASCADE;
+ ForeignKeyOauth2ProviderAppTokensAPIKeyID ForeignKeyConstraint = "oauth2_provider_app_tokens_api_key_id_fkey" // ALTER TABLE ONLY oauth2_provider_app_tokens ADD CONSTRAINT oauth2_provider_app_tokens_api_key_id_fkey FOREIGN KEY (api_key_id) REFERENCES api_keys(id) ON DELETE CASCADE;
+ ForeignKeyOauth2ProviderAppTokensAppSecretID ForeignKeyConstraint = "oauth2_provider_app_tokens_app_secret_id_fkey" // ALTER TABLE ONLY oauth2_provider_app_tokens ADD CONSTRAINT oauth2_provider_app_tokens_app_secret_id_fkey FOREIGN KEY (app_secret_id) REFERENCES oauth2_provider_app_secrets(id) ON DELETE CASCADE;
+ ForeignKeyOrganizationMembersOrganizationIDUUID ForeignKeyConstraint = "organization_members_organization_id_uuid_fkey" // ALTER TABLE ONLY organization_members ADD CONSTRAINT organization_members_organization_id_uuid_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
+ ForeignKeyOrganizationMembersUserIDUUID ForeignKeyConstraint = "organization_members_user_id_uuid_fkey" // ALTER TABLE ONLY organization_members ADD CONSTRAINT organization_members_user_id_uuid_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
+ ForeignKeyParameterSchemasJobID ForeignKeyConstraint = "parameter_schemas_job_id_fkey" // ALTER TABLE ONLY parameter_schemas ADD CONSTRAINT parameter_schemas_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
+ ForeignKeyProvisionerDaemonsKeyID ForeignKeyConstraint = "provisioner_daemons_key_id_fkey" // ALTER TABLE ONLY provisioner_daemons ADD CONSTRAINT provisioner_daemons_key_id_fkey FOREIGN KEY (key_id) REFERENCES provisioner_keys(id) ON DELETE CASCADE;
+ ForeignKeyProvisionerDaemonsOrganizationID ForeignKeyConstraint = "provisioner_daemons_organization_id_fkey" // ALTER TABLE ONLY provisioner_daemons ADD CONSTRAINT provisioner_daemons_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
+ ForeignKeyProvisionerJobLogsJobID ForeignKeyConstraint = "provisioner_job_logs_job_id_fkey" // ALTER TABLE ONLY provisioner_job_logs ADD CONSTRAINT provisioner_job_logs_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
+ ForeignKeyProvisionerJobTimingsJobID ForeignKeyConstraint = "provisioner_job_timings_job_id_fkey" // ALTER TABLE ONLY provisioner_job_timings ADD CONSTRAINT provisioner_job_timings_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
+ ForeignKeyProvisionerJobsOrganizationID ForeignKeyConstraint = "provisioner_jobs_organization_id_fkey" // ALTER TABLE ONLY provisioner_jobs ADD CONSTRAINT provisioner_jobs_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
+ ForeignKeyProvisionerKeysOrganizationID ForeignKeyConstraint = "provisioner_keys_organization_id_fkey" // ALTER TABLE ONLY provisioner_keys ADD CONSTRAINT provisioner_keys_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
+ ForeignKeyTailnetAgentsCoordinatorID ForeignKeyConstraint = "tailnet_agents_coordinator_id_fkey" // ALTER TABLE ONLY tailnet_agents ADD CONSTRAINT tailnet_agents_coordinator_id_fkey FOREIGN KEY (coordinator_id) REFERENCES tailnet_coordinators(id) ON DELETE CASCADE;
+ ForeignKeyTailnetClientSubscriptionsCoordinatorID ForeignKeyConstraint = "tailnet_client_subscriptions_coordinator_id_fkey" // ALTER TABLE ONLY tailnet_client_subscriptions ADD CONSTRAINT tailnet_client_subscriptions_coordinator_id_fkey FOREIGN KEY (coordinator_id) REFERENCES tailnet_coordinators(id) ON DELETE CASCADE;
+ ForeignKeyTailnetClientsCoordinatorID ForeignKeyConstraint = "tailnet_clients_coordinator_id_fkey" // ALTER TABLE ONLY tailnet_clients ADD CONSTRAINT tailnet_clients_coordinator_id_fkey FOREIGN KEY (coordinator_id) REFERENCES tailnet_coordinators(id) ON DELETE CASCADE;
+ ForeignKeyTailnetPeersCoordinatorID ForeignKeyConstraint = "tailnet_peers_coordinator_id_fkey" // ALTER TABLE ONLY tailnet_peers ADD CONSTRAINT tailnet_peers_coordinator_id_fkey FOREIGN KEY (coordinator_id) REFERENCES tailnet_coordinators(id) ON DELETE CASCADE;
+ ForeignKeyTailnetTunnelsCoordinatorID ForeignKeyConstraint = "tailnet_tunnels_coordinator_id_fkey" // ALTER TABLE ONLY tailnet_tunnels ADD CONSTRAINT tailnet_tunnels_coordinator_id_fkey FOREIGN KEY (coordinator_id) REFERENCES tailnet_coordinators(id) ON DELETE CASCADE;
+ ForeignKeyTemplateVersionParametersTemplateVersionID ForeignKeyConstraint = "template_version_parameters_template_version_id_fkey" // ALTER TABLE ONLY template_version_parameters ADD CONSTRAINT template_version_parameters_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
+ ForeignKeyTemplateVersionPresetParametTemplateVersionPresetID ForeignKeyConstraint = "template_version_preset_paramet_template_version_preset_id_fkey" // ALTER TABLE ONLY template_version_preset_parameters ADD CONSTRAINT template_version_preset_paramet_template_version_preset_id_fkey FOREIGN KEY (template_version_preset_id) REFERENCES template_version_presets(id) ON DELETE CASCADE;
+ ForeignKeyTemplateVersionPresetsTemplateVersionID ForeignKeyConstraint = "template_version_presets_template_version_id_fkey" // ALTER TABLE ONLY template_version_presets ADD CONSTRAINT template_version_presets_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
+ ForeignKeyTemplateVersionVariablesTemplateVersionID ForeignKeyConstraint = "template_version_variables_template_version_id_fkey" // ALTER TABLE ONLY template_version_variables ADD CONSTRAINT template_version_variables_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
+ ForeignKeyTemplateVersionWorkspaceTagsTemplateVersionID ForeignKeyConstraint = "template_version_workspace_tags_template_version_id_fkey" // ALTER TABLE ONLY template_version_workspace_tags ADD CONSTRAINT template_version_workspace_tags_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
+ ForeignKeyTemplateVersionsCreatedBy ForeignKeyConstraint = "template_versions_created_by_fkey" // ALTER TABLE ONLY template_versions ADD CONSTRAINT template_versions_created_by_fkey FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE RESTRICT;
+ ForeignKeyTemplateVersionsOrganizationID ForeignKeyConstraint = "template_versions_organization_id_fkey" // ALTER TABLE ONLY template_versions ADD CONSTRAINT template_versions_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
+ ForeignKeyTemplateVersionsTemplateID ForeignKeyConstraint = "template_versions_template_id_fkey" // ALTER TABLE ONLY template_versions ADD CONSTRAINT template_versions_template_id_fkey FOREIGN KEY (template_id) REFERENCES templates(id) ON DELETE CASCADE;
+ ForeignKeyTemplatesCreatedBy ForeignKeyConstraint = "templates_created_by_fkey" // ALTER TABLE ONLY templates ADD CONSTRAINT templates_created_by_fkey FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE RESTRICT;
+ ForeignKeyTemplatesOrganizationID ForeignKeyConstraint = "templates_organization_id_fkey" // ALTER TABLE ONLY templates ADD CONSTRAINT templates_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
+ ForeignKeyUserDeletedUserID ForeignKeyConstraint = "user_deleted_user_id_fkey" // ALTER TABLE ONLY user_deleted ADD CONSTRAINT user_deleted_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id);
+ ForeignKeyUserLinksOauthAccessTokenKeyID ForeignKeyConstraint = "user_links_oauth_access_token_key_id_fkey" // ALTER TABLE ONLY user_links ADD CONSTRAINT user_links_oauth_access_token_key_id_fkey FOREIGN KEY (oauth_access_token_key_id) REFERENCES dbcrypt_keys(active_key_digest);
+ ForeignKeyUserLinksOauthRefreshTokenKeyID ForeignKeyConstraint = "user_links_oauth_refresh_token_key_id_fkey" // ALTER TABLE ONLY user_links ADD CONSTRAINT user_links_oauth_refresh_token_key_id_fkey FOREIGN KEY (oauth_refresh_token_key_id) REFERENCES dbcrypt_keys(active_key_digest);
+ ForeignKeyUserLinksUserID ForeignKeyConstraint = "user_links_user_id_fkey" // ALTER TABLE ONLY user_links ADD CONSTRAINT user_links_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
+ ForeignKeyUserStatusChangesUserID ForeignKeyConstraint = "user_status_changes_user_id_fkey" // ALTER TABLE ONLY user_status_changes ADD CONSTRAINT user_status_changes_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id);
+ ForeignKeyWorkspaceAgentLogSourcesWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_log_sources_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_log_sources ADD CONSTRAINT workspace_agent_log_sources_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
+ ForeignKeyWorkspaceAgentMemoryResourceMonitorsAgentID ForeignKeyConstraint = "workspace_agent_memory_resource_monitors_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_memory_resource_monitors ADD CONSTRAINT workspace_agent_memory_resource_monitors_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
+ ForeignKeyWorkspaceAgentMetadataWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_metadata_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_metadata ADD CONSTRAINT workspace_agent_metadata_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
+ ForeignKeyWorkspaceAgentPortShareWorkspaceID ForeignKeyConstraint = "workspace_agent_port_share_workspace_id_fkey" // ALTER TABLE ONLY workspace_agent_port_share ADD CONSTRAINT workspace_agent_port_share_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE;
+ ForeignKeyWorkspaceAgentScriptTimingsScriptID ForeignKeyConstraint = "workspace_agent_script_timings_script_id_fkey" // ALTER TABLE ONLY workspace_agent_script_timings ADD CONSTRAINT workspace_agent_script_timings_script_id_fkey FOREIGN KEY (script_id) REFERENCES workspace_agent_scripts(id) ON DELETE CASCADE;
+ ForeignKeyWorkspaceAgentScriptsWorkspaceAgentID ForeignKeyConstraint = "workspace_agent_scripts_workspace_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_scripts ADD CONSTRAINT workspace_agent_scripts_workspace_agent_id_fkey FOREIGN KEY (workspace_agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
+ ForeignKeyWorkspaceAgentStartupLogsAgentID ForeignKeyConstraint = "workspace_agent_startup_logs_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_logs ADD CONSTRAINT workspace_agent_startup_logs_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
+ ForeignKeyWorkspaceAgentVolumeResourceMonitorsAgentID ForeignKeyConstraint = "workspace_agent_volume_resource_monitors_agent_id_fkey" // ALTER TABLE ONLY workspace_agent_volume_resource_monitors ADD CONSTRAINT workspace_agent_volume_resource_monitors_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
+ ForeignKeyWorkspaceAgentsResourceID ForeignKeyConstraint = "workspace_agents_resource_id_fkey" // ALTER TABLE ONLY workspace_agents ADD CONSTRAINT workspace_agents_resource_id_fkey FOREIGN KEY (resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE;
+ ForeignKeyWorkspaceAppStatsAgentID ForeignKeyConstraint = "workspace_app_stats_agent_id_fkey" // ALTER TABLE ONLY workspace_app_stats ADD CONSTRAINT workspace_app_stats_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id);
+ ForeignKeyWorkspaceAppStatsUserID ForeignKeyConstraint = "workspace_app_stats_user_id_fkey" // ALTER TABLE ONLY workspace_app_stats ADD CONSTRAINT workspace_app_stats_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id);
+ ForeignKeyWorkspaceAppStatsWorkspaceID ForeignKeyConstraint = "workspace_app_stats_workspace_id_fkey" // ALTER TABLE ONLY workspace_app_stats ADD CONSTRAINT workspace_app_stats_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id);
+ ForeignKeyWorkspaceAppsAgentID ForeignKeyConstraint = "workspace_apps_agent_id_fkey" // ALTER TABLE ONLY workspace_apps ADD CONSTRAINT workspace_apps_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE;
+ ForeignKeyWorkspaceBuildParametersWorkspaceBuildID ForeignKeyConstraint = "workspace_build_parameters_workspace_build_id_fkey" // ALTER TABLE ONLY workspace_build_parameters ADD CONSTRAINT workspace_build_parameters_workspace_build_id_fkey FOREIGN KEY (workspace_build_id) REFERENCES workspace_builds(id) ON DELETE CASCADE;
+ ForeignKeyWorkspaceBuildsJobID ForeignKeyConstraint = "workspace_builds_job_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
+ ForeignKeyWorkspaceBuildsTemplateVersionID ForeignKeyConstraint = "workspace_builds_template_version_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
+ ForeignKeyWorkspaceBuildsTemplateVersionPresetID ForeignKeyConstraint = "workspace_builds_template_version_preset_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_template_version_preset_id_fkey FOREIGN KEY (template_version_preset_id) REFERENCES template_version_presets(id) ON DELETE SET NULL;
+ ForeignKeyWorkspaceBuildsWorkspaceID ForeignKeyConstraint = "workspace_builds_workspace_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE;
+ ForeignKeyWorkspaceModulesJobID ForeignKeyConstraint = "workspace_modules_job_id_fkey" // ALTER TABLE ONLY workspace_modules ADD CONSTRAINT workspace_modules_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
+ ForeignKeyWorkspaceResourceMetadataWorkspaceResourceID ForeignKeyConstraint = "workspace_resource_metadata_workspace_resource_id_fkey" // ALTER TABLE ONLY workspace_resource_metadata ADD CONSTRAINT workspace_resource_metadata_workspace_resource_id_fkey FOREIGN KEY (workspace_resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE;
+ ForeignKeyWorkspaceResourcesJobID ForeignKeyConstraint = "workspace_resources_job_id_fkey" // ALTER TABLE ONLY workspace_resources ADD CONSTRAINT workspace_resources_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
+ ForeignKeyWorkspacesOrganizationID ForeignKeyConstraint = "workspaces_organization_id_fkey" // ALTER TABLE ONLY workspaces ADD CONSTRAINT workspaces_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE RESTRICT;
+ ForeignKeyWorkspacesOwnerID ForeignKeyConstraint = "workspaces_owner_id_fkey" // ALTER TABLE ONLY workspaces ADD CONSTRAINT workspaces_owner_id_fkey FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE RESTRICT;
+ ForeignKeyWorkspacesTemplateID ForeignKeyConstraint = "workspaces_template_id_fkey" // ALTER TABLE ONLY workspaces ADD CONSTRAINT workspaces_template_id_fkey FOREIGN KEY (template_id) REFERENCES templates(id) ON DELETE RESTRICT;
)
diff --git a/coderd/database/migrations/000291_workspace_parameter_presets.down.sql b/coderd/database/migrations/000291_workspace_parameter_presets.down.sql
new file mode 100644
index 0000000000000..487c4b1ab6a0c
--- /dev/null
+++ b/coderd/database/migrations/000291_workspace_parameter_presets.down.sql
@@ -0,0 +1,29 @@
+-- DROP the workspace_build_with_user view so that we can recreate without
+-- workspace_builds.template_version_preset_id below. We need to drop the view
+-- before dropping workspace_builds.template_version_preset_id because the view
+-- references it. We can only recreate the view after dropping the column,
+-- because the view needs to be created without the column.
+DROP VIEW workspace_build_with_user;
+
+ALTER TABLE workspace_builds
+DROP COLUMN template_version_preset_id;
+
+DROP TABLE template_version_preset_parameters;
+
+DROP TABLE template_version_presets;
+
+CREATE VIEW
+ workspace_build_with_user
+AS
+SELECT
+ workspace_builds.*,
+ coalesce(visible_users.avatar_url, '') AS initiator_by_avatar_url,
+ coalesce(visible_users.username, '') AS initiator_by_username
+FROM
+ workspace_builds
+ LEFT JOIN
+ visible_users
+ ON
+ workspace_builds.initiator_id = visible_users.id;
+
+COMMENT ON VIEW workspace_build_with_user IS 'Joins in the username + avatar url of the initiated by user.';
diff --git a/coderd/database/migrations/000291_workspace_parameter_presets.up.sql b/coderd/database/migrations/000291_workspace_parameter_presets.up.sql
new file mode 100644
index 0000000000000..d4a768081ec05
--- /dev/null
+++ b/coderd/database/migrations/000291_workspace_parameter_presets.up.sql
@@ -0,0 +1,44 @@
+CREATE TABLE template_version_presets
+(
+ id UUID PRIMARY KEY NOT NULL,
+ template_version_id UUID NOT NULL,
+ name TEXT NOT NULL,
+ created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (template_version_id) REFERENCES template_versions (id) ON DELETE CASCADE
+);
+
+CREATE TABLE template_version_preset_parameters
+(
+ id UUID PRIMARY KEY NOT NULL,
+ template_version_preset_id UUID NOT NULL,
+ name TEXT NOT NULL,
+ value TEXT NOT NULL,
+ FOREIGN KEY (template_version_preset_id) REFERENCES template_version_presets (id) ON DELETE CASCADE
+);
+
+ALTER TABLE workspace_builds
+ADD COLUMN template_version_preset_id UUID NULL;
+
+ALTER TABLE workspace_builds
+ADD CONSTRAINT workspace_builds_template_version_preset_id_fkey
+FOREIGN KEY (template_version_preset_id)
+REFERENCES template_version_presets (id)
+ON DELETE SET NULL;
+
+-- Recreate the view to include the new column.
+DROP VIEW workspace_build_with_user;
+CREATE VIEW
+ workspace_build_with_user
+AS
+SELECT
+ workspace_builds.*,
+ coalesce(visible_users.avatar_url, '') AS initiator_by_avatar_url,
+ coalesce(visible_users.username, '') AS initiator_by_username
+FROM
+ workspace_builds
+ LEFT JOIN
+ visible_users
+ ON
+ workspace_builds.initiator_id = visible_users.id;
+
+COMMENT ON VIEW workspace_build_with_user IS 'Joins in the username + avatar url of the initiated by user.';
diff --git a/coderd/database/migrations/testdata/fixtures/000291_workspace_parameter_presets.up.sql b/coderd/database/migrations/testdata/fixtures/000291_workspace_parameter_presets.up.sql
new file mode 100644
index 0000000000000..8eebf58e3f39c
--- /dev/null
+++ b/coderd/database/migrations/testdata/fixtures/000291_workspace_parameter_presets.up.sql
@@ -0,0 +1,10 @@
+INSERT INTO public.organizations (id, name, description, created_at, updated_at, is_default, display_name, icon) VALUES ('20362772-802a-4a72-8e4f-3648b4bfd168', 'strange_hopper58', 'wizardly_stonebraker60', '2025-02-07 07:46:19.507551 +00:00', '2025-02-07 07:46:19.507552 +00:00', false, 'competent_rhodes59', '');
+
+INSERT INTO public.users (id, email, username, hashed_password, created_at, updated_at, status, rbac_roles, login_type, avatar_url, deleted, last_seen_at, quiet_hours_schedule, theme_preference, name, github_com_user_id, hashed_one_time_passcode, one_time_passcode_expires_at) VALUES ('6c353aac-20de-467b-bdfb-3c30a37adcd2', 'vigorous_murdock61', 'affectionate_hawking62', 'lqTu9C5363AwD7NVNH6noaGjp91XIuZJ', '2025-02-07 07:46:19.510861 +00:00', '2025-02-07 07:46:19.512949 +00:00', 'active', '{}', 'password', '', false, '0001-01-01 00:00:00.000000', '', '', 'vigilant_hugle63', null, null, null);
+
+INSERT INTO public.templates (id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, autostop_requirement_days_of_week, autostop_requirement_weeks, autostart_block_days_of_week, require_active_version, deprecated, activity_bump, max_port_sharing_level) VALUES ('6b298946-7a4f-47ac-9158-b03b08740a41', '2025-02-07 07:46:19.513317 +00:00', '2025-02-07 07:46:19.513317 +00:00', '20362772-802a-4a72-8e4f-3648b4bfd168', false, 'modest_leakey64', 'echo', 'e6cfa2a4-e4cf-4182-9e19-08b975682a28', 'upbeat_wright65', 604800000000000, '6c353aac-20de-467b-bdfb-3c30a37adcd2', 'nervous_keller66', '{}', '{"20362772-802a-4a72-8e4f-3648b4bfd168": ["read", "use"]}', 'determined_aryabhata67', false, true, true, 0, 0, 0, 0, 0, 0, false, '', 3600000000000, 'owner');
+INSERT INTO public.template_versions (id, template_id, organization_id, created_at, updated_at, name, readme, job_id, created_by, external_auth_providers, message, archived, source_example_id) VALUES ('af58bd62-428c-4c33-849b-d43a3be07d93', '6b298946-7a4f-47ac-9158-b03b08740a41', '20362772-802a-4a72-8e4f-3648b4bfd168', '2025-02-07 07:46:19.514782 +00:00', '2025-02-07 07:46:19.514782 +00:00', 'distracted_shockley68', 'sleepy_turing69', 'f2e2ea1c-5aa3-4a1d-8778-2e5071efae59', '6c353aac-20de-467b-bdfb-3c30a37adcd2', '[]', '', false, null);
+
+INSERT INTO public.template_version_presets (id, template_version_id, name, created_at) VALUES ('28b42cc0-c4fe-4907-a0fe-e4d20f1e9bfe', 'af58bd62-428c-4c33-849b-d43a3be07d93', 'test', '0001-01-01 00:00:00.000000 +00:00');
+
+INSERT INTO public.template_version_preset_parameters (id, template_version_preset_id, name, value) VALUES ('ea90ccd2-5024-459e-87e4-879afd24de0f', '28b42cc0-c4fe-4907-a0fe-e4d20f1e9bfe', 'test', 'test');
diff --git a/coderd/database/models.go b/coderd/database/models.go
index 6a5a061ad93c4..fc11e1f4f5ebe 100644
--- a/coderd/database/models.go
+++ b/coderd/database/models.go
@@ -2954,6 +2954,20 @@ type TemplateVersionParameter struct {
Ephemeral bool `db:"ephemeral" json:"ephemeral"`
}
+type TemplateVersionPreset struct {
+ ID uuid.UUID `db:"id" json:"id"`
+ TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"`
+ Name string `db:"name" json:"name"`
+ CreatedAt time.Time `db:"created_at" json:"created_at"`
+}
+
+type TemplateVersionPresetParameter struct {
+ ID uuid.UUID `db:"id" json:"id"`
+ TemplateVersionPresetID uuid.UUID `db:"template_version_preset_id" json:"template_version_preset_id"`
+ Name string `db:"name" json:"name"`
+ Value string `db:"value" json:"value"`
+}
+
type TemplateVersionTable struct {
ID uuid.UUID `db:"id" json:"id"`
TemplateID uuid.NullUUID `db:"template_id" json:"template_id"`
@@ -3283,22 +3297,23 @@ type WorkspaceAppStat struct {
// Joins in the username + avatar url of the initiated by user.
type WorkspaceBuild struct {
- ID uuid.UUID `db:"id" json:"id"`
- CreatedAt time.Time `db:"created_at" json:"created_at"`
- UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
- WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
- TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"`
- BuildNumber int32 `db:"build_number" json:"build_number"`
- Transition WorkspaceTransition `db:"transition" json:"transition"`
- InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
- ProvisionerState []byte `db:"provisioner_state" json:"provisioner_state"`
- JobID uuid.UUID `db:"job_id" json:"job_id"`
- Deadline time.Time `db:"deadline" json:"deadline"`
- Reason BuildReason `db:"reason" json:"reason"`
- DailyCost int32 `db:"daily_cost" json:"daily_cost"`
- MaxDeadline time.Time `db:"max_deadline" json:"max_deadline"`
- InitiatorByAvatarUrl string `db:"initiator_by_avatar_url" json:"initiator_by_avatar_url"`
- InitiatorByUsername string `db:"initiator_by_username" json:"initiator_by_username"`
+ ID uuid.UUID `db:"id" json:"id"`
+ CreatedAt time.Time `db:"created_at" json:"created_at"`
+ UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
+ WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
+ TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"`
+ BuildNumber int32 `db:"build_number" json:"build_number"`
+ Transition WorkspaceTransition `db:"transition" json:"transition"`
+ InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
+ ProvisionerState []byte `db:"provisioner_state" json:"provisioner_state"`
+ JobID uuid.UUID `db:"job_id" json:"job_id"`
+ Deadline time.Time `db:"deadline" json:"deadline"`
+ Reason BuildReason `db:"reason" json:"reason"`
+ DailyCost int32 `db:"daily_cost" json:"daily_cost"`
+ MaxDeadline time.Time `db:"max_deadline" json:"max_deadline"`
+ TemplateVersionPresetID uuid.NullUUID `db:"template_version_preset_id" json:"template_version_preset_id"`
+ InitiatorByAvatarUrl string `db:"initiator_by_avatar_url" json:"initiator_by_avatar_url"`
+ InitiatorByUsername string `db:"initiator_by_username" json:"initiator_by_username"`
}
type WorkspaceBuildParameter struct {
@@ -3310,20 +3325,21 @@ type WorkspaceBuildParameter struct {
}
type WorkspaceBuildTable struct {
- ID uuid.UUID `db:"id" json:"id"`
- CreatedAt time.Time `db:"created_at" json:"created_at"`
- UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
- WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
- TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"`
- BuildNumber int32 `db:"build_number" json:"build_number"`
- Transition WorkspaceTransition `db:"transition" json:"transition"`
- InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
- ProvisionerState []byte `db:"provisioner_state" json:"provisioner_state"`
- JobID uuid.UUID `db:"job_id" json:"job_id"`
- Deadline time.Time `db:"deadline" json:"deadline"`
- Reason BuildReason `db:"reason" json:"reason"`
- DailyCost int32 `db:"daily_cost" json:"daily_cost"`
- MaxDeadline time.Time `db:"max_deadline" json:"max_deadline"`
+ ID uuid.UUID `db:"id" json:"id"`
+ CreatedAt time.Time `db:"created_at" json:"created_at"`
+ UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
+ WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
+ TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"`
+ BuildNumber int32 `db:"build_number" json:"build_number"`
+ Transition WorkspaceTransition `db:"transition" json:"transition"`
+ InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
+ ProvisionerState []byte `db:"provisioner_state" json:"provisioner_state"`
+ JobID uuid.UUID `db:"job_id" json:"job_id"`
+ Deadline time.Time `db:"deadline" json:"deadline"`
+ Reason BuildReason `db:"reason" json:"reason"`
+ DailyCost int32 `db:"daily_cost" json:"daily_cost"`
+ MaxDeadline time.Time `db:"max_deadline" json:"max_deadline"`
+ TemplateVersionPresetID uuid.NullUUID `db:"template_version_preset_id" json:"template_version_preset_id"`
}
type WorkspaceModule struct {
diff --git a/coderd/database/querier.go b/coderd/database/querier.go
index 13eb9e2e75cde..5f9856028b985 100644
--- a/coderd/database/querier.go
+++ b/coderd/database/querier.go
@@ -202,6 +202,9 @@ type sqlcQuerier interface {
GetOrganizations(ctx context.Context, arg GetOrganizationsParams) ([]Organization, error)
GetOrganizationsByUserID(ctx context.Context, userID uuid.UUID) ([]Organization, error)
GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUID) ([]ParameterSchema, error)
+ GetPresetByWorkspaceBuildID(ctx context.Context, workspaceBuildID uuid.UUID) (TemplateVersionPreset, error)
+ GetPresetParametersByTemplateVersionID(ctx context.Context, templateVersionID uuid.UUID) ([]TemplateVersionPresetParameter, error)
+ GetPresetsByTemplateVersionID(ctx context.Context, templateVersionID uuid.UUID) ([]TemplateVersionPreset, error)
GetPreviousTemplateVersion(ctx context.Context, arg GetPreviousTemplateVersionParams) (TemplateVersion, error)
GetProvisionerDaemons(ctx context.Context) ([]ProvisionerDaemon, error)
GetProvisionerDaemonsByOrganization(ctx context.Context, arg GetProvisionerDaemonsByOrganizationParams) ([]ProvisionerDaemon, error)
@@ -404,6 +407,8 @@ type sqlcQuerier interface {
InsertOAuth2ProviderAppToken(ctx context.Context, arg InsertOAuth2ProviderAppTokenParams) (OAuth2ProviderAppToken, error)
InsertOrganization(ctx context.Context, arg InsertOrganizationParams) (Organization, error)
InsertOrganizationMember(ctx context.Context, arg InsertOrganizationMemberParams) (OrganizationMember, error)
+ InsertPreset(ctx context.Context, arg InsertPresetParams) (TemplateVersionPreset, error)
+ InsertPresetParameters(ctx context.Context, arg InsertPresetParametersParams) ([]TemplateVersionPresetParameter, error)
InsertProvisionerJob(ctx context.Context, arg InsertProvisionerJobParams) (ProvisionerJob, error)
InsertProvisionerJobLogs(ctx context.Context, arg InsertProvisionerJobLogsParams) ([]ProvisionerJobLog, error)
InsertProvisionerJobTimings(ctx context.Context, arg InsertProvisionerJobTimingsParams) ([]ProvisionerJobTiming, error)
diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go
index 7653094a22e2b..60f05064b76ee 100644
--- a/coderd/database/queries.sql.go
+++ b/coderd/database/queries.sql.go
@@ -5395,6 +5395,185 @@ func (q *sqlQuerier) GetParameterSchemasByJobID(ctx context.Context, jobID uuid.
return items, nil
}
+const getPresetByWorkspaceBuildID = `-- name: GetPresetByWorkspaceBuildID :one
+SELECT
+ template_version_presets.id, template_version_presets.template_version_id, template_version_presets.name, template_version_presets.created_at
+FROM
+ template_version_presets
+ INNER JOIN workspace_builds ON workspace_builds.template_version_preset_id = template_version_presets.id
+WHERE
+ workspace_builds.id = $1
+`
+
+func (q *sqlQuerier) GetPresetByWorkspaceBuildID(ctx context.Context, workspaceBuildID uuid.UUID) (TemplateVersionPreset, error) {
+ row := q.db.QueryRowContext(ctx, getPresetByWorkspaceBuildID, workspaceBuildID)
+ var i TemplateVersionPreset
+ err := row.Scan(
+ &i.ID,
+ &i.TemplateVersionID,
+ &i.Name,
+ &i.CreatedAt,
+ )
+ return i, err
+}
+
+const getPresetParametersByTemplateVersionID = `-- name: GetPresetParametersByTemplateVersionID :many
+SELECT
+ template_version_preset_parameters.id, template_version_preset_parameters.template_version_preset_id, template_version_preset_parameters.name, template_version_preset_parameters.value
+FROM
+ template_version_preset_parameters
+ INNER JOIN template_version_presets ON template_version_preset_parameters.template_version_preset_id = template_version_presets.id
+WHERE
+ template_version_presets.template_version_id = $1
+`
+
+func (q *sqlQuerier) GetPresetParametersByTemplateVersionID(ctx context.Context, templateVersionID uuid.UUID) ([]TemplateVersionPresetParameter, error) {
+ rows, err := q.db.QueryContext(ctx, getPresetParametersByTemplateVersionID, templateVersionID)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+ var items []TemplateVersionPresetParameter
+ for rows.Next() {
+ var i TemplateVersionPresetParameter
+ if err := rows.Scan(
+ &i.ID,
+ &i.TemplateVersionPresetID,
+ &i.Name,
+ &i.Value,
+ ); err != nil {
+ return nil, err
+ }
+ items = append(items, i)
+ }
+ if err := rows.Close(); err != nil {
+ return nil, err
+ }
+ if err := rows.Err(); err != nil {
+ return nil, err
+ }
+ return items, nil
+}
+
+const getPresetsByTemplateVersionID = `-- name: GetPresetsByTemplateVersionID :many
+SELECT
+ id, template_version_id, name, created_at
+FROM
+ template_version_presets
+WHERE
+ template_version_id = $1
+`
+
+func (q *sqlQuerier) GetPresetsByTemplateVersionID(ctx context.Context, templateVersionID uuid.UUID) ([]TemplateVersionPreset, error) {
+ rows, err := q.db.QueryContext(ctx, getPresetsByTemplateVersionID, templateVersionID)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+ var items []TemplateVersionPreset
+ for rows.Next() {
+ var i TemplateVersionPreset
+ if err := rows.Scan(
+ &i.ID,
+ &i.TemplateVersionID,
+ &i.Name,
+ &i.CreatedAt,
+ ); err != nil {
+ return nil, err
+ }
+ items = append(items, i)
+ }
+ if err := rows.Close(); err != nil {
+ return nil, err
+ }
+ if err := rows.Err(); err != nil {
+ return nil, err
+ }
+ return items, nil
+}
+
+const insertPreset = `-- name: InsertPreset :one
+INSERT INTO
+ template_version_presets (id, template_version_id, name, created_at)
+VALUES
+ ($1, $2, $3, $4) RETURNING id, template_version_id, name, created_at
+`
+
+type InsertPresetParams struct {
+ ID uuid.UUID `db:"id" json:"id"`
+ TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"`
+ Name string `db:"name" json:"name"`
+ CreatedAt time.Time `db:"created_at" json:"created_at"`
+}
+
+func (q *sqlQuerier) InsertPreset(ctx context.Context, arg InsertPresetParams) (TemplateVersionPreset, error) {
+ row := q.db.QueryRowContext(ctx, insertPreset,
+ arg.ID,
+ arg.TemplateVersionID,
+ arg.Name,
+ arg.CreatedAt,
+ )
+ var i TemplateVersionPreset
+ err := row.Scan(
+ &i.ID,
+ &i.TemplateVersionID,
+ &i.Name,
+ &i.CreatedAt,
+ )
+ return i, err
+}
+
+const insertPresetParameters = `-- name: InsertPresetParameters :many
+INSERT INTO
+ template_version_preset_parameters (id, template_version_preset_id, name, value)
+SELECT
+ $1,
+ $2,
+ unnest($3 :: TEXT[]),
+ unnest($4 :: TEXT[])
+RETURNING id, template_version_preset_id, name, value
+`
+
+type InsertPresetParametersParams struct {
+ ID uuid.UUID `db:"id" json:"id"`
+ TemplateVersionPresetID uuid.UUID `db:"template_version_preset_id" json:"template_version_preset_id"`
+ Names []string `db:"names" json:"names"`
+ Values []string `db:"values" json:"values"`
+}
+
+func (q *sqlQuerier) InsertPresetParameters(ctx context.Context, arg InsertPresetParametersParams) ([]TemplateVersionPresetParameter, error) {
+ rows, err := q.db.QueryContext(ctx, insertPresetParameters,
+ arg.ID,
+ arg.TemplateVersionPresetID,
+ pq.Array(arg.Names),
+ pq.Array(arg.Values),
+ )
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+ var items []TemplateVersionPresetParameter
+ for rows.Next() {
+ var i TemplateVersionPresetParameter
+ if err := rows.Scan(
+ &i.ID,
+ &i.TemplateVersionPresetID,
+ &i.Name,
+ &i.Value,
+ ); err != nil {
+ return nil, err
+ }
+ items = append(items, i)
+ }
+ if err := rows.Close(); err != nil {
+ return nil, err
+ }
+ if err := rows.Err(); err != nil {
+ return nil, err
+ }
+ return items, nil
+}
+
const deleteOldProvisionerDaemons = `-- name: DeleteOldProvisionerDaemons :exec
DELETE FROM provisioner_daemons WHERE (
(created_at < (NOW() - INTERVAL '7 days') AND last_seen_at IS NULL) OR
@@ -11993,7 +12172,7 @@ const getWorkspaceAgentAndLatestBuildByAuthToken = `-- name: GetWorkspaceAgentAn
SELECT
workspaces.id, workspaces.created_at, workspaces.updated_at, workspaces.owner_id, workspaces.organization_id, workspaces.template_id, workspaces.deleted, workspaces.name, workspaces.autostart_schedule, workspaces.ttl, workspaces.last_used_at, workspaces.dormant_at, workspaces.deleting_at, workspaces.automatic_updates, workspaces.favorite, workspaces.next_start_at,
workspace_agents.id, workspace_agents.created_at, workspace_agents.updated_at, workspace_agents.name, workspace_agents.first_connected_at, workspace_agents.last_connected_at, workspace_agents.disconnected_at, workspace_agents.resource_id, workspace_agents.auth_token, workspace_agents.auth_instance_id, workspace_agents.architecture, workspace_agents.environment_variables, workspace_agents.operating_system, workspace_agents.instance_metadata, workspace_agents.resource_metadata, workspace_agents.directory, workspace_agents.version, workspace_agents.last_connected_replica_id, workspace_agents.connection_timeout_seconds, workspace_agents.troubleshooting_url, workspace_agents.motd_file, workspace_agents.lifecycle_state, workspace_agents.expanded_directory, workspace_agents.logs_length, workspace_agents.logs_overflowed, workspace_agents.started_at, workspace_agents.ready_at, workspace_agents.subsystems, workspace_agents.display_apps, workspace_agents.api_version, workspace_agents.display_order,
- workspace_build_with_user.id, workspace_build_with_user.created_at, workspace_build_with_user.updated_at, workspace_build_with_user.workspace_id, workspace_build_with_user.template_version_id, workspace_build_with_user.build_number, workspace_build_with_user.transition, workspace_build_with_user.initiator_id, workspace_build_with_user.provisioner_state, workspace_build_with_user.job_id, workspace_build_with_user.deadline, workspace_build_with_user.reason, workspace_build_with_user.daily_cost, workspace_build_with_user.max_deadline, workspace_build_with_user.initiator_by_avatar_url, workspace_build_with_user.initiator_by_username
+ workspace_build_with_user.id, workspace_build_with_user.created_at, workspace_build_with_user.updated_at, workspace_build_with_user.workspace_id, workspace_build_with_user.template_version_id, workspace_build_with_user.build_number, workspace_build_with_user.transition, workspace_build_with_user.initiator_id, workspace_build_with_user.provisioner_state, workspace_build_with_user.job_id, workspace_build_with_user.deadline, workspace_build_with_user.reason, workspace_build_with_user.daily_cost, workspace_build_with_user.max_deadline, workspace_build_with_user.template_version_preset_id, workspace_build_with_user.initiator_by_avatar_url, workspace_build_with_user.initiator_by_username
FROM
workspace_agents
JOIN
@@ -12096,6 +12275,7 @@ func (q *sqlQuerier) GetWorkspaceAgentAndLatestBuildByAuthToken(ctx context.Cont
&i.WorkspaceBuild.Reason,
&i.WorkspaceBuild.DailyCost,
&i.WorkspaceBuild.MaxDeadline,
+ &i.WorkspaceBuild.TemplateVersionPresetID,
&i.WorkspaceBuild.InitiatorByAvatarUrl,
&i.WorkspaceBuild.InitiatorByUsername,
)
@@ -14299,7 +14479,7 @@ func (q *sqlQuerier) InsertWorkspaceBuildParameters(ctx context.Context, arg Ins
}
const getActiveWorkspaceBuildsByTemplateID = `-- name: GetActiveWorkspaceBuildsByTemplateID :many
-SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline, wb.reason, wb.daily_cost, wb.max_deadline, wb.initiator_by_avatar_url, wb.initiator_by_username
+SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline, wb.reason, wb.daily_cost, wb.max_deadline, wb.template_version_preset_id, wb.initiator_by_avatar_url, wb.initiator_by_username
FROM (
SELECT
workspace_id, MAX(build_number) as max_build_number
@@ -14353,6 +14533,7 @@ func (q *sqlQuerier) GetActiveWorkspaceBuildsByTemplateID(ctx context.Context, t
&i.Reason,
&i.DailyCost,
&i.MaxDeadline,
+ &i.TemplateVersionPresetID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
); err != nil {
@@ -14448,7 +14629,7 @@ func (q *sqlQuerier) GetFailedWorkspaceBuildsByTemplateID(ctx context.Context, a
const getLatestWorkspaceBuildByWorkspaceID = `-- name: GetLatestWorkspaceBuildByWorkspaceID :one
SELECT
- id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, initiator_by_avatar_url, initiator_by_username
+ id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, initiator_by_avatar_url, initiator_by_username
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -14477,6 +14658,7 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildByWorkspaceID(ctx context.Context, w
&i.Reason,
&i.DailyCost,
&i.MaxDeadline,
+ &i.TemplateVersionPresetID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
)
@@ -14484,7 +14666,7 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildByWorkspaceID(ctx context.Context, w
}
const getLatestWorkspaceBuilds = `-- name: GetLatestWorkspaceBuilds :many
-SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline, wb.reason, wb.daily_cost, wb.max_deadline, wb.initiator_by_avatar_url, wb.initiator_by_username
+SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline, wb.reason, wb.daily_cost, wb.max_deadline, wb.template_version_preset_id, wb.initiator_by_avatar_url, wb.initiator_by_username
FROM (
SELECT
workspace_id, MAX(build_number) as max_build_number
@@ -14522,6 +14704,7 @@ func (q *sqlQuerier) GetLatestWorkspaceBuilds(ctx context.Context) ([]WorkspaceB
&i.Reason,
&i.DailyCost,
&i.MaxDeadline,
+ &i.TemplateVersionPresetID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
); err != nil {
@@ -14539,7 +14722,7 @@ func (q *sqlQuerier) GetLatestWorkspaceBuilds(ctx context.Context) ([]WorkspaceB
}
const getLatestWorkspaceBuildsByWorkspaceIDs = `-- name: GetLatestWorkspaceBuildsByWorkspaceIDs :many
-SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline, wb.reason, wb.daily_cost, wb.max_deadline, wb.initiator_by_avatar_url, wb.initiator_by_username
+SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline, wb.reason, wb.daily_cost, wb.max_deadline, wb.template_version_preset_id, wb.initiator_by_avatar_url, wb.initiator_by_username
FROM (
SELECT
workspace_id, MAX(build_number) as max_build_number
@@ -14579,6 +14762,7 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildsByWorkspaceIDs(ctx context.Context,
&i.Reason,
&i.DailyCost,
&i.MaxDeadline,
+ &i.TemplateVersionPresetID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
); err != nil {
@@ -14597,7 +14781,7 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildsByWorkspaceIDs(ctx context.Context,
const getWorkspaceBuildByID = `-- name: GetWorkspaceBuildByID :one
SELECT
- id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, initiator_by_avatar_url, initiator_by_username
+ id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, initiator_by_avatar_url, initiator_by_username
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -14624,6 +14808,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByID(ctx context.Context, id uuid.UUID) (W
&i.Reason,
&i.DailyCost,
&i.MaxDeadline,
+ &i.TemplateVersionPresetID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
)
@@ -14632,7 +14817,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByID(ctx context.Context, id uuid.UUID) (W
const getWorkspaceBuildByJobID = `-- name: GetWorkspaceBuildByJobID :one
SELECT
- id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, initiator_by_avatar_url, initiator_by_username
+ id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, initiator_by_avatar_url, initiator_by_username
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -14659,6 +14844,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByJobID(ctx context.Context, jobID uuid.UU
&i.Reason,
&i.DailyCost,
&i.MaxDeadline,
+ &i.TemplateVersionPresetID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
)
@@ -14667,7 +14853,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByJobID(ctx context.Context, jobID uuid.UU
const getWorkspaceBuildByWorkspaceIDAndBuildNumber = `-- name: GetWorkspaceBuildByWorkspaceIDAndBuildNumber :one
SELECT
- id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, initiator_by_avatar_url, initiator_by_username
+ id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, initiator_by_avatar_url, initiator_by_username
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -14698,6 +14884,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceIDAndBuildNumber(ctx context.Co
&i.Reason,
&i.DailyCost,
&i.MaxDeadline,
+ &i.TemplateVersionPresetID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
)
@@ -14773,7 +14960,7 @@ func (q *sqlQuerier) GetWorkspaceBuildStatsByTemplates(ctx context.Context, sinc
const getWorkspaceBuildsByWorkspaceID = `-- name: GetWorkspaceBuildsByWorkspaceID :many
SELECT
- id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, initiator_by_avatar_url, initiator_by_username
+ id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, initiator_by_avatar_url, initiator_by_username
FROM
workspace_build_with_user AS workspace_builds
WHERE
@@ -14843,6 +15030,7 @@ func (q *sqlQuerier) GetWorkspaceBuildsByWorkspaceID(ctx context.Context, arg Ge
&i.Reason,
&i.DailyCost,
&i.MaxDeadline,
+ &i.TemplateVersionPresetID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
); err != nil {
@@ -14860,7 +15048,7 @@ func (q *sqlQuerier) GetWorkspaceBuildsByWorkspaceID(ctx context.Context, arg Ge
}
const getWorkspaceBuildsCreatedAfter = `-- name: GetWorkspaceBuildsCreatedAfter :many
-SELECT id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, initiator_by_avatar_url, initiator_by_username FROM workspace_build_with_user WHERE created_at > $1
+SELECT id, created_at, updated_at, workspace_id, template_version_id, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason, daily_cost, max_deadline, template_version_preset_id, initiator_by_avatar_url, initiator_by_username FROM workspace_build_with_user WHERE created_at > $1
`
func (q *sqlQuerier) GetWorkspaceBuildsCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceBuild, error) {
@@ -14887,6 +15075,7 @@ func (q *sqlQuerier) GetWorkspaceBuildsCreatedAfter(ctx context.Context, created
&i.Reason,
&i.DailyCost,
&i.MaxDeadline,
+ &i.TemplateVersionPresetID,
&i.InitiatorByAvatarUrl,
&i.InitiatorByUsername,
); err != nil {
@@ -14918,26 +15107,28 @@ INSERT INTO
provisioner_state,
deadline,
max_deadline,
- reason
+ reason,
+ template_version_preset_id
)
VALUES
- ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
+ ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
`
type InsertWorkspaceBuildParams struct {
- ID uuid.UUID `db:"id" json:"id"`
- CreatedAt time.Time `db:"created_at" json:"created_at"`
- UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
- WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
- TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"`
- BuildNumber int32 `db:"build_number" json:"build_number"`
- Transition WorkspaceTransition `db:"transition" json:"transition"`
- InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
- JobID uuid.UUID `db:"job_id" json:"job_id"`
- ProvisionerState []byte `db:"provisioner_state" json:"provisioner_state"`
- Deadline time.Time `db:"deadline" json:"deadline"`
- MaxDeadline time.Time `db:"max_deadline" json:"max_deadline"`
- Reason BuildReason `db:"reason" json:"reason"`
+ ID uuid.UUID `db:"id" json:"id"`
+ CreatedAt time.Time `db:"created_at" json:"created_at"`
+ UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
+ WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
+ TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"`
+ BuildNumber int32 `db:"build_number" json:"build_number"`
+ Transition WorkspaceTransition `db:"transition" json:"transition"`
+ InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
+ JobID uuid.UUID `db:"job_id" json:"job_id"`
+ ProvisionerState []byte `db:"provisioner_state" json:"provisioner_state"`
+ Deadline time.Time `db:"deadline" json:"deadline"`
+ MaxDeadline time.Time `db:"max_deadline" json:"max_deadline"`
+ Reason BuildReason `db:"reason" json:"reason"`
+ TemplateVersionPresetID uuid.NullUUID `db:"template_version_preset_id" json:"template_version_preset_id"`
}
func (q *sqlQuerier) InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspaceBuildParams) error {
@@ -14955,6 +15146,7 @@ func (q *sqlQuerier) InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspa
arg.Deadline,
arg.MaxDeadline,
arg.Reason,
+ arg.TemplateVersionPresetID,
)
return err
}
diff --git a/coderd/database/queries/presets.sql b/coderd/database/queries/presets.sql
new file mode 100644
index 0000000000000..6bfe31dc09ceb
--- /dev/null
+++ b/coderd/database/queries/presets.sql
@@ -0,0 +1,41 @@
+-- name: InsertPreset :one
+INSERT INTO
+ template_version_presets (id, template_version_id, name, created_at)
+VALUES
+ (@id, @template_version_id, @name, @created_at) RETURNING *;
+
+-- name: InsertPresetParameters :many
+INSERT INTO
+ template_version_preset_parameters (id, template_version_preset_id, name, value)
+SELECT
+ @id,
+ @template_version_preset_id,
+ unnest(@names :: TEXT[]),
+ unnest(@values :: TEXT[])
+RETURNING *;
+
+-- name: GetPresetsByTemplateVersionID :many
+SELECT
+ *
+FROM
+ template_version_presets
+WHERE
+ template_version_id = @template_version_id;
+
+-- name: GetPresetByWorkspaceBuildID :one
+SELECT
+ template_version_presets.*
+FROM
+ template_version_presets
+ INNER JOIN workspace_builds ON workspace_builds.template_version_preset_id = template_version_presets.id
+WHERE
+ workspace_builds.id = @workspace_build_id;
+
+-- name: GetPresetParametersByTemplateVersionID :many
+SELECT
+ template_version_preset_parameters.*
+FROM
+ template_version_preset_parameters
+ INNER JOIN template_version_presets ON template_version_preset_parameters.template_version_preset_id = template_version_presets.id
+WHERE
+ template_version_presets.template_version_id = @template_version_id;
diff --git a/coderd/database/queries/workspacebuilds.sql b/coderd/database/queries/workspacebuilds.sql
index 7050b61644e86..da349fa1441b3 100644
--- a/coderd/database/queries/workspacebuilds.sql
+++ b/coderd/database/queries/workspacebuilds.sql
@@ -120,10 +120,11 @@ INSERT INTO
provisioner_state,
deadline,
max_deadline,
- reason
+ reason,
+ template_version_preset_id
)
VALUES
- ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13);
+ ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14);
-- name: UpdateWorkspaceBuildCostByID :exec
UPDATE
diff --git a/coderd/database/unique_constraint.go b/coderd/database/unique_constraint.go
index e372983250c4b..ce427cf97c3bc 100644
--- a/coderd/database/unique_constraint.go
+++ b/coderd/database/unique_constraint.go
@@ -58,6 +58,8 @@ const (
UniqueTelemetryItemsPkey UniqueConstraint = "telemetry_items_pkey" // ALTER TABLE ONLY telemetry_items ADD CONSTRAINT telemetry_items_pkey PRIMARY KEY (key);
UniqueTemplateUsageStatsPkey UniqueConstraint = "template_usage_stats_pkey" // ALTER TABLE ONLY template_usage_stats ADD CONSTRAINT template_usage_stats_pkey PRIMARY KEY (start_time, template_id, user_id);
UniqueTemplateVersionParametersTemplateVersionIDNameKey UniqueConstraint = "template_version_parameters_template_version_id_name_key" // ALTER TABLE ONLY template_version_parameters ADD CONSTRAINT template_version_parameters_template_version_id_name_key UNIQUE (template_version_id, name);
+ UniqueTemplateVersionPresetParametersPkey UniqueConstraint = "template_version_preset_parameters_pkey" // ALTER TABLE ONLY template_version_preset_parameters ADD CONSTRAINT template_version_preset_parameters_pkey PRIMARY KEY (id);
+ UniqueTemplateVersionPresetsPkey UniqueConstraint = "template_version_presets_pkey" // ALTER TABLE ONLY template_version_presets ADD CONSTRAINT template_version_presets_pkey PRIMARY KEY (id);
UniqueTemplateVersionVariablesTemplateVersionIDNameKey UniqueConstraint = "template_version_variables_template_version_id_name_key" // ALTER TABLE ONLY template_version_variables ADD CONSTRAINT template_version_variables_template_version_id_name_key UNIQUE (template_version_id, name);
UniqueTemplateVersionWorkspaceTagsTemplateVersionIDKeyKey UniqueConstraint = "template_version_workspace_tags_template_version_id_key_key" // ALTER TABLE ONLY template_version_workspace_tags ADD CONSTRAINT template_version_workspace_tags_template_version_id_key_key UNIQUE (template_version_id, key);
UniqueTemplateVersionsPkey UniqueConstraint = "template_versions_pkey" // ALTER TABLE ONLY template_versions ADD CONSTRAINT template_versions_pkey PRIMARY KEY (id);
diff --git a/coderd/wsbuilder/wsbuilder.go b/coderd/wsbuilder/wsbuilder.go
index 3d757f4c5590b..183fdf2d447cc 100644
--- a/coderd/wsbuilder/wsbuilder.go
+++ b/coderd/wsbuilder/wsbuilder.go
@@ -376,6 +376,10 @@ func (b *Builder) buildTx(authFunc func(action policy.Action, object rbac.Object
Reason: b.reason,
Deadline: time.Time{}, // set by provisioner upon completion
MaxDeadline: time.Time{}, // set by provisioner upon completion
+ TemplateVersionPresetID: uuid.NullUUID{
+ UUID: uuid.Nil,
+ Valid: false,
+ },
})
if err != nil {
code := http.StatusInternalServerError
diff --git a/docs/admin/security/audit-logs.md b/docs/admin/security/audit-logs.md
index 85e3a17e34665..2131e7746d2d6 100644
--- a/docs/admin/security/audit-logs.md
+++ b/docs/admin/security/audit-logs.md
@@ -29,7 +29,7 @@ We track the following resources:
| Template
write, delete |
Field | Tracked |
| active_version_id | true |
activity_bump | true |
allow_user_autostart | true |
allow_user_autostop | true |
allow_user_cancel_workspace_jobs | true |
autostart_block_days_of_week | true |
autostop_requirement_days_of_week | true |
autostop_requirement_weeks | true |
created_at | false |
created_by | true |
created_by_avatar_url | false |
created_by_username | false |
default_ttl | true |
deleted | false |
deprecated | true |
description | true |
display_name | true |
failure_ttl | true |
group_acl | true |
icon | true |
id | true |
max_port_sharing_level | true |
name | true |
organization_display_name | false |
organization_icon | false |
organization_id | false |
organization_name | false |
provisioner | true |
require_active_version | true |
time_til_dormant | true |
time_til_dormant_autodelete | true |
updated_at | false |
user_acl | true |
|
| TemplateVersion
create, write | Field | Tracked |
| archived | true |
created_at | false |
created_by | true |
created_by_avatar_url | false |
created_by_username | false |
external_auth_providers | false |
id | true |
job_id | false |
message | false |
name | true |
organization_id | false |
readme | true |
source_example_id | false |
template_id | true |
updated_at | false |
|
| User
create, write, delete | Field | Tracked |
| avatar_url | false |
created_at | false |
deleted | true |
email | true |
github_com_user_id | false |
hashed_one_time_passcode | false |
hashed_password | true |
id | true |
last_seen_at | false |
login_type | true |
name | true |
one_time_passcode_expires_at | true |
quiet_hours_schedule | true |
rbac_roles | true |
status | true |
theme_preference | false |
updated_at | false |
username | true |
|
-| WorkspaceBuild
start, stop | Field | Tracked |
| build_number | false |
created_at | false |
daily_cost | false |
deadline | false |
id | false |
initiator_by_avatar_url | false |
initiator_by_username | false |
initiator_id | false |
job_id | false |
max_deadline | false |
provisioner_state | false |
reason | false |
template_version_id | true |
transition | false |
updated_at | false |
workspace_id | false |
|
+| WorkspaceBuild
start, stop | Field | Tracked |
| build_number | false |
created_at | false |
daily_cost | false |
deadline | false |
id | false |
initiator_by_avatar_url | false |
initiator_by_username | false |
initiator_id | false |
job_id | false |
max_deadline | false |
provisioner_state | false |
reason | false |
template_version_id | true |
template_version_preset_id | false |
transition | false |
updated_at | false |
workspace_id | false |
|
| WorkspaceProxy
| Field | Tracked |
| created_at | true |
deleted | false |
derp_enabled | true |
derp_only | true |
display_name | true |
icon | true |
id | true |
name | true |
region_id | true |
token_hashed_secret | true |
updated_at | false |
url | true |
version | true |
wildcard_hostname | true |
|
| WorkspaceTable
| Field | Tracked |
| automatic_updates | true |
autostart_schedule | true |
created_at | false |
deleted | false |
deleting_at | true |
dormant_at | true |
favorite | true |
id | true |
last_used_at | false |
name | true |
next_start_at | true |
organization_id | false |
owner_id | true |
template_id | true |
ttl | true |
updated_at | false |
|
diff --git a/enterprise/audit/table.go b/enterprise/audit/table.go
index b72a64c2eeae4..d43b2e224e374 100644
--- a/enterprise/audit/table.go
+++ b/enterprise/audit/table.go
@@ -170,22 +170,23 @@ var auditableResourcesTypes = map[any]map[string]Action{
"next_start_at": ActionTrack,
},
&database.WorkspaceBuild{}: {
- "id": ActionIgnore,
- "created_at": ActionIgnore,
- "updated_at": ActionIgnore,
- "workspace_id": ActionIgnore,
- "template_version_id": ActionTrack,
- "build_number": ActionIgnore,
- "transition": ActionIgnore,
- "initiator_id": ActionIgnore,
- "provisioner_state": ActionIgnore,
- "job_id": ActionIgnore,
- "deadline": ActionIgnore,
- "reason": ActionIgnore,
- "daily_cost": ActionIgnore,
- "max_deadline": ActionIgnore,
- "initiator_by_avatar_url": ActionIgnore,
- "initiator_by_username": ActionIgnore,
+ "id": ActionIgnore,
+ "created_at": ActionIgnore,
+ "updated_at": ActionIgnore,
+ "workspace_id": ActionIgnore,
+ "template_version_id": ActionTrack,
+ "build_number": ActionIgnore,
+ "transition": ActionIgnore,
+ "initiator_id": ActionIgnore,
+ "provisioner_state": ActionIgnore,
+ "job_id": ActionIgnore,
+ "deadline": ActionIgnore,
+ "reason": ActionIgnore,
+ "daily_cost": ActionIgnore,
+ "max_deadline": ActionIgnore,
+ "initiator_by_avatar_url": ActionIgnore,
+ "initiator_by_username": ActionIgnore,
+ "template_version_preset_id": ActionIgnore, // Never changes.
},
&database.AuditableGroup{}: {
"id": ActionTrack,