Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

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

Provide feedback

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

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd6ba0df

Browse files
authored
feat: add "updated" search param to workspaces (#11714)
* feat: add "updated" search param to workspaces* rego -> sql needs to specify which <table>.organization_id
1 parent081fbef commitd6ba0df

File tree

10 files changed

+159
-25
lines changed

10 files changed

+159
-25
lines changed

‎coderd/database/dbmem/dbmem.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7534,6 +7534,23 @@ func (q *FakeQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg database.
75347534
}
75357535
}
75367536

7537+
ifarg.UsingActive.Valid {
7538+
build,err:=q.getLatestWorkspaceBuildByWorkspaceIDNoLock(ctx,workspace.ID)
7539+
iferr!=nil {
7540+
returnnil,xerrors.Errorf("get latest build: %w",err)
7541+
}
7542+
7543+
template,err:=q.getTemplateByIDNoLock(ctx,workspace.TemplateID)
7544+
iferr!=nil {
7545+
returnnil,xerrors.Errorf("get template: %w",err)
7546+
}
7547+
7548+
updated:=build.TemplateVersionID==template.ActiveVersionID
7549+
ifarg.UsingActive.Bool!=updated {
7550+
continue
7551+
}
7552+
}
7553+
75377554
if!arg.Deleted&&workspace.Deleted {
75387555
continue
75397556
}

‎coderd/database/modelqueries.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ type workspaceQuerier interface {
198198
// This code is copied from `GetWorkspaces` and adds the authorized filter WHERE
199199
// clause.
200200
func (q*sqlQuerier)GetAuthorizedWorkspaces(ctx context.Context,argGetWorkspacesParams,prepared rbac.PreparedAuthorized) ([]GetWorkspacesRow,error) {
201-
authorizedFilter,err:=prepared.CompileToSQL(ctx,rbac.ConfigWithoutACL())
201+
authorizedFilter,err:=prepared.CompileToSQL(ctx,rbac.ConfigWorkspaces())
202202
iferr!=nil {
203203
returnnil,xerrors.Errorf("compile authorized filter: %w",err)
204204
}
@@ -225,6 +225,7 @@ func (q *sqlQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspa
225225
arg.Dormant,
226226
arg.LastUsedBefore,
227227
arg.LastUsedAfter,
228+
arg.UsingActive,
228229
arg.Offset,
229230
arg.Limit,
230231
)

‎coderd/database/queries.sql.go

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

‎coderd/database/queries/workspaces.sql

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ WHERE
7979
-- name: GetWorkspaces :many
8080
SELECT
8181
workspaces.*,
82-
COALESCE(template_name.template_name,'unknown')as template_name,
82+
COALESCE(template.name,'unknown')as template_name,
8383
latest_build.template_version_id,
8484
latest_build.template_version_name,
8585
COUNT(*) OVER ()as count
@@ -120,12 +120,12 @@ LEFT JOIN LATERAL (
120120
) latest_buildON TRUE
121121
LEFT JOIN LATERAL (
122122
SELECT
123-
templates.nameAS template_name
123+
*
124124
FROM
125125
templates
126126
WHERE
127127
templates.id=workspaces.template_id
128-
)template_nameON true
128+
)templateON true
129129
WHERE
130130
-- Optionally include deleted workspaces
131131
workspaces.deleted= @deleted
@@ -259,6 +259,11 @@ WHERE
259259
workspaces.last_used_at>= @last_used_after
260260
ELSE true
261261
END
262+
AND CASE
263+
WHENsqlc.narg('using_active') ::booleanIS NOT NULL THEN
264+
(latest_build.template_version_id=template.active_version_id)=sqlc.narg('using_active') ::boolean
265+
ELSE true
266+
END
262267
-- Authorize Filter clause will be injected below in GetAuthorizedWorkspaces
263268
-- @authorize_filter
264269
ORDER BY

‎coderd/rbac/authz.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,12 @@ func ConfigWithoutACL() regosql.ConvertConfig {
611611
}
612612
}
613613

614+
funcConfigWorkspaces() regosql.ConvertConfig {
615+
return regosql.ConvertConfig{
616+
VariableConverter:regosql.WorkspaceConverter(),
617+
}
618+
}
619+
614620
funcCompile(cfg regosql.ConvertConfig,pa*PartialAuthorizer) (AuthorizeFilter,error) {
615621
root,err:=regosql.ConvertRegoAst(cfg,pa.partialQueries)
616622
iferr!=nil {

‎coderd/rbac/regosql/configs.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,20 @@ func UserConverter() *sqltypes.VariableConverter {
5353
returnmatcher
5454
}
5555

56+
funcWorkspaceConverter()*sqltypes.VariableConverter {
57+
matcher:=sqltypes.NewVariableConverter().RegisterMatcher(
58+
resourceIDMatcher(),
59+
sqltypes.StringVarMatcher("workspaces.organization_id :: text", []string{"input","object","org_owner"}),
60+
userOwnerMatcher(),
61+
)
62+
matcher.RegisterMatcher(
63+
sqltypes.AlwaysFalse(groupACLMatcher(matcher)),
64+
sqltypes.AlwaysFalse(userACLMatcher(matcher)),
65+
)
66+
67+
returnmatcher
68+
}
69+
5670
// NoACLConverter should be used when the target SQL table does not contain
5771
// group or user ACL columns.
5872
funcNoACLConverter()*sqltypes.VariableConverter {

‎coderd/searchquery/search.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package searchquery
22

33
import (
4+
"database/sql"
45
"fmt"
56
"net/url"
67
"strings"
@@ -110,6 +111,14 @@ func Workspaces(query string, page codersdk.Pagination, agentInactiveDisconnectT
110111
filter.Dormant=parser.Boolean(values,false,"dormant")
111112
filter.LastUsedAfter=parser.Time3339Nano(values, time.Time{},"last_used_after")
112113
filter.LastUsedBefore=parser.Time3339Nano(values, time.Time{},"last_used_before")
114+
filter.UsingActive= sql.NullBool{
115+
// Invert the value of the query parameter to get the correct value.
116+
// UsingActive returns if the workspace is on the latest template active version.
117+
Bool:!parser.Boolean(values,true,"outdated"),
118+
// Only include this search term if it was provided. Otherwise default to omitting it
119+
// which will return all workspaces.
120+
Valid:values.Has("outdated"),
121+
}
113122

114123
parser.ErrorExcessParams(values)
115124
returnfilter,parser.Errors

‎coderd/searchquery/search_test.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package searchquery_test
22

33
import (
4+
"database/sql"
45
"fmt"
56
"strings"
67
"testing"
@@ -116,7 +117,26 @@ func TestSearchWorkspace(t *testing.T) {
116117
OwnerUsername:"foo",
117118
},
118119
},
119-
120+
{
121+
Name:"Outdated",
122+
Query:`outdated:true`,
123+
Expected: database.GetWorkspacesParams{
124+
UsingActive: sql.NullBool{
125+
Bool:false,
126+
Valid:true,
127+
},
128+
},
129+
},
130+
{
131+
Name:"Updated",
132+
Query:`outdated:false`,
133+
Expected: database.GetWorkspacesParams{
134+
UsingActive: sql.NullBool{
135+
Bool:true,
136+
Valid:true,
137+
},
138+
},
139+
},
120140
// Failures
121141
{
122142
Name:"NoPrefix",

‎coderd/workspaces_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,6 +1632,56 @@ func TestWorkspaceFilterManual(t *testing.T) {
16321632
require.Len(t,afterRes.Workspaces,1)
16331633
require.Equal(t,after.ID,afterRes.Workspaces[0].ID)
16341634
})
1635+
t.Run("Updated",func(t*testing.T) {
1636+
t.Parallel()
1637+
client:=coderdtest.New(t,&coderdtest.Options{IncludeProvisionerDaemon:true})
1638+
user:=coderdtest.CreateFirstUser(t,client)
1639+
version:=coderdtest.CreateTemplateVersion(t,client,user.OrganizationID,nil)
1640+
coderdtest.AwaitTemplateVersionJobCompleted(t,client,version.ID)
1641+
template:=coderdtest.CreateTemplate(t,client,user.OrganizationID,version.ID)
1642+
workspace:=coderdtest.CreateWorkspace(t,client,user.OrganizationID,template.ID)
1643+
1644+
ctx,cancel:=context.WithTimeout(context.Background(),testutil.WaitLong)
1645+
defercancel()
1646+
1647+
// Workspace is up-to-date
1648+
res,err:=client.Workspaces(ctx, codersdk.WorkspaceFilter{
1649+
FilterQuery:"outdated:false",
1650+
})
1651+
require.NoError(t,err)
1652+
require.Len(t,res.Workspaces,1)
1653+
require.Equal(t,workspace.ID,res.Workspaces[0].ID)
1654+
1655+
res,err=client.Workspaces(ctx, codersdk.WorkspaceFilter{
1656+
FilterQuery:"outdated:true",
1657+
})
1658+
require.NoError(t,err)
1659+
require.Len(t,res.Workspaces,0)
1660+
1661+
// Now make it out of date
1662+
newTv:=coderdtest.CreateTemplateVersion(t,client,user.OrganizationID,nil,func(request*codersdk.CreateTemplateVersionRequest) {
1663+
request.TemplateID=template.ID
1664+
})
1665+
coderdtest.AwaitTemplateVersionJobCompleted(t,client,version.ID)
1666+
err=client.UpdateActiveTemplateVersion(ctx,template.ID, codersdk.UpdateActiveTemplateVersion{
1667+
ID:newTv.ID,
1668+
})
1669+
require.NoError(t,err)
1670+
1671+
// Check the query again
1672+
res,err=client.Workspaces(ctx, codersdk.WorkspaceFilter{
1673+
FilterQuery:"outdated:false",
1674+
})
1675+
require.NoError(t,err)
1676+
require.Len(t,res.Workspaces,0)
1677+
1678+
res,err=client.Workspaces(ctx, codersdk.WorkspaceFilter{
1679+
FilterQuery:"outdated:true",
1680+
})
1681+
require.NoError(t,err)
1682+
require.Len(t,res.Workspaces,1)
1683+
require.Equal(t,workspace.ID,res.Workspaces[0].ID)
1684+
})
16351685
}
16361686

16371687
funcTestOffsetLimit(t*testing.T) {

‎site/src/pages/WorkspacesPage/filter/filter.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export const workspaceFilterQuery = {
2222
running:"status:running",
2323
failed:"status:failed",
2424
dormant:"dormant:true",
25+
outdated:"outdated:true",
2526
};
2627

2728
typeFilterPreset={
@@ -48,6 +49,10 @@ const PRESET_FILTERS: FilterPreset[] = [
4849
query:workspaceFilterQuery.failed,
4950
name:"Failed workspaces",
5051
},
52+
{
53+
query:workspaceFilterQuery.outdated,
54+
name:"Outdated workspaces",
55+
},
5156
];
5257

5358
// Defined outside component so that the array doesn't get reconstructed each render

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp