feat: add frontend for locked workspaces (#8655)

- Fix workspaces query for locked workspaces.
This commit is contained in:
Jon Ayers
2023-08-03 19:46:02 -05:00
committed by GitHub
parent 502c7680a2
commit e43608395c
36 changed files with 665 additions and 193 deletions
+2 -2
View File
@@ -2587,11 +2587,11 @@ func (q *querier) UpdateWorkspaceLastUsedAt(ctx context.Context, arg database.Up
return update(q.log, q.auth, fetch, q.db.UpdateWorkspaceLastUsedAt)(ctx, arg)
}
func (q *querier) UpdateWorkspaceLockedDeletingAt(ctx context.Context, arg database.UpdateWorkspaceLockedDeletingAtParams) error {
func (q *querier) UpdateWorkspaceLockedDeletingAt(ctx context.Context, arg database.UpdateWorkspaceLockedDeletingAtParams) (database.Workspace, error) {
fetch := func(ctx context.Context, arg database.UpdateWorkspaceLockedDeletingAtParams) (database.Workspace, error) {
return q.db.GetWorkspaceByID(ctx, arg.ID)
}
return update(q.log, q.auth, fetch, q.db.UpdateWorkspaceLockedDeletingAt)(ctx, arg)
return updateWithReturn(q.log, q.auth, fetch, q.db.UpdateWorkspaceLockedDeletingAt)(ctx, arg)
}
func (q *querier) UpdateWorkspaceProxy(ctx context.Context, arg database.UpdateWorkspaceProxyParams) (database.WorkspaceProxy, error) {
+15 -5
View File
@@ -5250,9 +5250,9 @@ func (q *FakeQuerier) UpdateWorkspaceLastUsedAt(_ context.Context, arg database.
return sql.ErrNoRows
}
func (q *FakeQuerier) UpdateWorkspaceLockedDeletingAt(_ context.Context, arg database.UpdateWorkspaceLockedDeletingAtParams) error {
func (q *FakeQuerier) UpdateWorkspaceLockedDeletingAt(_ context.Context, arg database.UpdateWorkspaceLockedDeletingAtParams) (database.Workspace, error) {
if err := validateDatabaseType(arg); err != nil {
return err
return database.Workspace{}, err
}
q.mutex.Lock()
defer q.mutex.Unlock()
@@ -5274,7 +5274,7 @@ func (q *FakeQuerier) UpdateWorkspaceLockedDeletingAt(_ context.Context, arg dat
}
}
if template.ID == uuid.Nil {
return xerrors.Errorf("unable to find workspace template")
return database.Workspace{}, xerrors.Errorf("unable to find workspace template")
}
if template.LockedTTL > 0 {
workspace.DeletingAt = sql.NullTime{
@@ -5284,9 +5284,9 @@ func (q *FakeQuerier) UpdateWorkspaceLockedDeletingAt(_ context.Context, arg dat
}
}
q.workspaces[index] = workspace
return nil
return workspace, nil
}
return sql.ErrNoRows
return database.Workspace{}, sql.ErrNoRows
}
func (q *FakeQuerier) UpdateWorkspaceProxy(_ context.Context, arg database.UpdateWorkspaceProxyParams) (database.WorkspaceProxy, error) {
@@ -5730,6 +5730,16 @@ func (q *FakeQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg database.
}
}
// We omit locked workspaces by default.
if arg.LockedAt.IsZero() && workspace.LockedAt.Valid {
continue
}
// Filter out workspaces that are locked after the timestamp.
if !arg.LockedAt.IsZero() && workspace.LockedAt.Time.Before(arg.LockedAt) {
continue
}
if len(arg.TemplateIDs) > 0 {
match := false
for _, id := range arg.TemplateIDs {
+3 -3
View File
@@ -1572,11 +1572,11 @@ func (m metricsStore) UpdateWorkspaceLastUsedAt(ctx context.Context, arg databas
return err
}
func (m metricsStore) UpdateWorkspaceLockedDeletingAt(ctx context.Context, arg database.UpdateWorkspaceLockedDeletingAtParams) error {
func (m metricsStore) UpdateWorkspaceLockedDeletingAt(ctx context.Context, arg database.UpdateWorkspaceLockedDeletingAtParams) (database.Workspace, error) {
start := time.Now()
r0 := m.s.UpdateWorkspaceLockedDeletingAt(ctx, arg)
ws, r0 := m.s.UpdateWorkspaceLockedDeletingAt(ctx, arg)
m.queryLatencies.WithLabelValues("UpdateWorkspaceLockedDeletingAt").Observe(time.Since(start).Seconds())
return r0
return ws, r0
}
func (m metricsStore) UpdateWorkspaceProxy(ctx context.Context, arg database.UpdateWorkspaceProxyParams) (database.WorkspaceProxy, error) {
+4 -3
View File
@@ -3307,11 +3307,12 @@ func (mr *MockStoreMockRecorder) UpdateWorkspaceLastUsedAt(arg0, arg1 interface{
}
// UpdateWorkspaceLockedDeletingAt mocks base method.
func (m *MockStore) UpdateWorkspaceLockedDeletingAt(arg0 context.Context, arg1 database.UpdateWorkspaceLockedDeletingAtParams) error {
func (m *MockStore) UpdateWorkspaceLockedDeletingAt(arg0 context.Context, arg1 database.UpdateWorkspaceLockedDeletingAtParams) (database.Workspace, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateWorkspaceLockedDeletingAt", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
ret0, _ := ret[0].(database.Workspace)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// UpdateWorkspaceLockedDeletingAt indicates an expected call of UpdateWorkspaceLockedDeletingAt.
+1
View File
@@ -217,6 +217,7 @@ func (q *sqlQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspa
arg.Name,
arg.HasAgent,
arg.AgentInactiveDisconnectTimeoutSeconds,
arg.LockedAt,
arg.Offset,
arg.Limit,
)
+1 -1
View File
@@ -277,7 +277,7 @@ type sqlcQuerier interface {
UpdateWorkspaceBuildCostByID(ctx context.Context, arg UpdateWorkspaceBuildCostByIDParams) error
UpdateWorkspaceDeletedByID(ctx context.Context, arg UpdateWorkspaceDeletedByIDParams) error
UpdateWorkspaceLastUsedAt(ctx context.Context, arg UpdateWorkspaceLastUsedAtParams) error
UpdateWorkspaceLockedDeletingAt(ctx context.Context, arg UpdateWorkspaceLockedDeletingAtParams) error
UpdateWorkspaceLockedDeletingAt(ctx context.Context, arg UpdateWorkspaceLockedDeletingAtParams) (Workspace, error)
// This allows editing the properties of a workspace proxy.
UpdateWorkspaceProxy(ctx context.Context, arg UpdateWorkspaceProxyParams) (WorkspaceProxy, error)
UpdateWorkspaceProxyDeleted(ctx context.Context, arg UpdateWorkspaceProxyDeletedParams) error
+34 -7
View File
@@ -9001,6 +9001,14 @@ WHERE
) > 0
ELSE true
END
-- Filter by locked workspaces. By default we do not return locked
-- workspaces since they are considered soft-deleted.
AND CASE
WHEN $10 :: timestamptz > '0001-01-01 00:00:00+00'::timestamptz THEN
locked_at IS NOT NULL AND locked_at >= $10
ELSE
locked_at IS NULL
END
-- Authorize Filter clause will be injected below in GetAuthorizedWorkspaces
-- @authorize_filter
ORDER BY
@@ -9012,11 +9020,11 @@ ORDER BY
LOWER(workspaces.name) ASC
LIMIT
CASE
WHEN $11 :: integer > 0 THEN
$11
WHEN $12 :: integer > 0 THEN
$12
END
OFFSET
$10
$11
`
type GetWorkspacesParams struct {
@@ -9029,6 +9037,7 @@ type GetWorkspacesParams struct {
Name string `db:"name" json:"name"`
HasAgent string `db:"has_agent" json:"has_agent"`
AgentInactiveDisconnectTimeoutSeconds int64 `db:"agent_inactive_disconnect_timeout_seconds" json:"agent_inactive_disconnect_timeout_seconds"`
LockedAt time.Time `db:"locked_at" json:"locked_at"`
Offset int32 `db:"offset_" json:"offset_"`
Limit int32 `db:"limit_" json:"limit_"`
}
@@ -9064,6 +9073,7 @@ func (q *sqlQuerier) GetWorkspaces(ctx context.Context, arg GetWorkspacesParams)
arg.Name,
arg.HasAgent,
arg.AgentInactiveDisconnectTimeoutSeconds,
arg.LockedAt,
arg.Offset,
arg.Limit,
)
@@ -9366,7 +9376,7 @@ func (q *sqlQuerier) UpdateWorkspaceLastUsedAt(ctx context.Context, arg UpdateWo
return err
}
const updateWorkspaceLockedDeletingAt = `-- name: UpdateWorkspaceLockedDeletingAt :exec
const updateWorkspaceLockedDeletingAt = `-- name: UpdateWorkspaceLockedDeletingAt :one
UPDATE
workspaces
SET
@@ -9383,6 +9393,7 @@ WHERE
workspaces.template_id = templates.id
AND
workspaces.id = $1
RETURNING 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.locked_at, workspaces.deleting_at
`
type UpdateWorkspaceLockedDeletingAtParams struct {
@@ -9390,9 +9401,25 @@ type UpdateWorkspaceLockedDeletingAtParams struct {
LockedAt sql.NullTime `db:"locked_at" json:"locked_at"`
}
func (q *sqlQuerier) UpdateWorkspaceLockedDeletingAt(ctx context.Context, arg UpdateWorkspaceLockedDeletingAtParams) error {
_, err := q.db.ExecContext(ctx, updateWorkspaceLockedDeletingAt, arg.ID, arg.LockedAt)
return err
func (q *sqlQuerier) UpdateWorkspaceLockedDeletingAt(ctx context.Context, arg UpdateWorkspaceLockedDeletingAtParams) (Workspace, error) {
row := q.db.QueryRowContext(ctx, updateWorkspaceLockedDeletingAt, arg.ID, arg.LockedAt)
var i Workspace
err := row.Scan(
&i.ID,
&i.CreatedAt,
&i.UpdatedAt,
&i.OwnerID,
&i.OrganizationID,
&i.TemplateID,
&i.Deleted,
&i.Name,
&i.AutostartSchedule,
&i.Ttl,
&i.LastUsedAt,
&i.LockedAt,
&i.DeletingAt,
)
return i, err
}
const updateWorkspaceTTL = `-- name: UpdateWorkspaceTTL :exec
+11 -2
View File
@@ -259,6 +259,14 @@ WHERE
) > 0
ELSE true
END
-- Filter by locked workspaces. By default we do not return locked
-- workspaces since they are considered soft-deleted.
AND CASE
WHEN @locked_at :: timestamptz > '0001-01-01 00:00:00+00'::timestamptz THEN
locked_at IS NOT NULL AND locked_at >= @locked_at
ELSE
locked_at IS NULL
END
-- Authorize Filter clause will be injected below in GetAuthorizedWorkspaces
-- @authorize_filter
ORDER BY
@@ -474,7 +482,7 @@ WHERE
)
) AND workspaces.deleted = 'false';
-- name: UpdateWorkspaceLockedDeletingAt :exec
-- name: UpdateWorkspaceLockedDeletingAt :one
UPDATE
workspaces
SET
@@ -490,7 +498,8 @@ FROM
WHERE
workspaces.template_id = templates.id
AND
workspaces.id = $1;
workspaces.id = $1
RETURNING workspaces.*;
-- name: UpdateWorkspacesDeletingAtByTemplateID :exec
UPDATE