mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: add port-sharing backend (#11939)
This commit is contained in:
@@ -891,6 +891,20 @@ func (q *querier) DeleteTailnetTunnel(ctx context.Context, arg database.DeleteTa
|
||||
return q.db.DeleteTailnetTunnel(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) DeleteWorkspaceAgentPortShare(ctx context.Context, arg database.DeleteWorkspaceAgentPortShareParams) error {
|
||||
w, err := q.db.GetWorkspaceByID(ctx, arg.WorkspaceID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// deleting a workspace port share is more akin to just updating the workspace.
|
||||
if err = q.authorizeContext(ctx, rbac.ActionUpdate, w.RBACObject()); err != nil {
|
||||
return xerrors.Errorf("authorize context: %w", err)
|
||||
}
|
||||
|
||||
return q.db.DeleteWorkspaceAgentPortShare(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) FavoriteWorkspace(ctx context.Context, id uuid.UUID) error {
|
||||
fetch := func(ctx context.Context, id uuid.UUID) (database.Workspace, error) {
|
||||
return q.db.GetWorkspaceByID(ctx, id)
|
||||
@@ -1868,6 +1882,20 @@ func (q *querier) GetWorkspaceAgentMetadata(ctx context.Context, arg database.Ge
|
||||
return q.db.GetWorkspaceAgentMetadata(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetWorkspaceAgentPortShare(ctx context.Context, arg database.GetWorkspaceAgentPortShareParams) (database.WorkspaceAgentPortShare, error) {
|
||||
w, err := q.db.GetWorkspaceByID(ctx, arg.WorkspaceID)
|
||||
if err != nil {
|
||||
return database.WorkspaceAgentPortShare{}, err
|
||||
}
|
||||
|
||||
// reading a workspace port share is more akin to just reading the workspace.
|
||||
if err = q.authorizeContext(ctx, rbac.ActionRead, w.RBACObject()); err != nil {
|
||||
return database.WorkspaceAgentPortShare{}, xerrors.Errorf("authorize context: %w", err)
|
||||
}
|
||||
|
||||
return q.db.GetWorkspaceAgentPortShare(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetWorkspaceAgentScriptsByAgentIDs(ctx context.Context, ids []uuid.UUID) ([]database.WorkspaceAgentScript, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
@@ -2500,6 +2528,20 @@ func (q *querier) InsertWorkspaceResourceMetadata(ctx context.Context, arg datab
|
||||
return q.db.InsertWorkspaceResourceMetadata(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) ListWorkspaceAgentPortShares(ctx context.Context, workspaceID uuid.UUID) ([]database.WorkspaceAgentPortShare, error) {
|
||||
workspace, err := q.db.GetWorkspaceByID(ctx, workspaceID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// listing port shares is more akin to reading the workspace.
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, workspace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return q.db.ListWorkspaceAgentPortShares(ctx, workspaceID)
|
||||
}
|
||||
|
||||
func (q *querier) RegisterWorkspaceProxy(ctx context.Context, arg database.RegisterWorkspaceProxyParams) (database.WorkspaceProxy, error) {
|
||||
fetch := func(ctx context.Context, arg database.RegisterWorkspaceProxyParams) (database.WorkspaceProxy, error) {
|
||||
return q.db.GetWorkspaceProxyByID(ctx, arg.ID)
|
||||
@@ -3273,6 +3315,20 @@ func (q *querier) UpsertTailnetTunnel(ctx context.Context, arg database.UpsertTa
|
||||
return q.db.UpsertTailnetTunnel(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpsertWorkspaceAgentPortShare(ctx context.Context, arg database.UpsertWorkspaceAgentPortShareParams) (database.WorkspaceAgentPortShare, error) {
|
||||
workspace, err := q.db.GetWorkspaceByID(ctx, arg.WorkspaceID)
|
||||
if err != nil {
|
||||
return database.WorkspaceAgentPortShare{}, err
|
||||
}
|
||||
|
||||
err = q.authorizeContext(ctx, rbac.ActionUpdate, workspace)
|
||||
if err != nil {
|
||||
return database.WorkspaceAgentPortShare{}, err
|
||||
}
|
||||
|
||||
return q.db.UpsertWorkspaceAgentPortShare(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetAuthorizedTemplates(ctx context.Context, arg database.GetTemplatesWithFilterParams, _ rbac.PreparedAuthorized) ([]database.Template, error) {
|
||||
// TODO Delete this function, all GetTemplates should be authorized. For now just call getTemplates on the authz querier.
|
||||
return q.GetTemplatesWithFilter(ctx, arg)
|
||||
|
||||
@@ -822,8 +822,9 @@ func (s *MethodTestSuite) TestTemplate() {
|
||||
s.Run("InsertTemplate", s.Subtest(func(db database.Store, check *expects) {
|
||||
orgID := uuid.New()
|
||||
check.Args(database.InsertTemplateParams{
|
||||
Provisioner: "echo",
|
||||
OrganizationID: orgID,
|
||||
Provisioner: "echo",
|
||||
OrganizationID: orgID,
|
||||
MaxPortSharingLevel: database.AppSharingLevelOwner,
|
||||
}).Asserts(rbac.ResourceTemplate.InOrg(orgID), rbac.ActionCreate)
|
||||
}))
|
||||
s.Run("InsertTemplateVersion", s.Subtest(func(db database.Store, check *expects) {
|
||||
@@ -890,7 +891,8 @@ func (s *MethodTestSuite) TestTemplate() {
|
||||
s.Run("UpdateTemplateMetaByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
t1 := dbgen.Template(s.T(), db, database.Template{})
|
||||
check.Args(database.UpdateTemplateMetaByIDParams{
|
||||
ID: t1.ID,
|
||||
ID: t1.ID,
|
||||
MaxPortSharingLevel: "owner",
|
||||
}).Asserts(t1, rbac.ActionUpdate)
|
||||
}))
|
||||
s.Run("UpdateTemplateVersionByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
@@ -1601,6 +1603,47 @@ func (s *MethodTestSuite) TestWorkspace() {
|
||||
}))
|
||||
}
|
||||
|
||||
func (s *MethodTestSuite) TestWorkspacePortSharing() {
|
||||
s.Run("UpsertWorkspaceAgentPortShare", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
ws := dbgen.Workspace(s.T(), db, database.Workspace{OwnerID: u.ID})
|
||||
ps := dbgen.WorkspaceAgentPortShare(s.T(), db, database.WorkspaceAgentPortShare{WorkspaceID: ws.ID})
|
||||
//nolint:gosimple // casting is not a simplification
|
||||
check.Args(database.UpsertWorkspaceAgentPortShareParams{
|
||||
WorkspaceID: ps.WorkspaceID,
|
||||
AgentName: ps.AgentName,
|
||||
Port: ps.Port,
|
||||
ShareLevel: ps.ShareLevel,
|
||||
}).Asserts(ws, rbac.ActionUpdate).Returns(ps)
|
||||
}))
|
||||
s.Run("GetWorkspaceAgentPortShare", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
ws := dbgen.Workspace(s.T(), db, database.Workspace{OwnerID: u.ID})
|
||||
ps := dbgen.WorkspaceAgentPortShare(s.T(), db, database.WorkspaceAgentPortShare{WorkspaceID: ws.ID})
|
||||
check.Args(database.GetWorkspaceAgentPortShareParams{
|
||||
WorkspaceID: ps.WorkspaceID,
|
||||
AgentName: ps.AgentName,
|
||||
Port: ps.Port,
|
||||
}).Asserts(ws, rbac.ActionRead).Returns(ps)
|
||||
}))
|
||||
s.Run("ListWorkspaceAgentPortShares", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
ws := dbgen.Workspace(s.T(), db, database.Workspace{OwnerID: u.ID})
|
||||
ps := dbgen.WorkspaceAgentPortShare(s.T(), db, database.WorkspaceAgentPortShare{WorkspaceID: ws.ID})
|
||||
check.Args(ws.ID).Asserts(ws, rbac.ActionRead).Returns([]database.WorkspaceAgentPortShare{ps})
|
||||
}))
|
||||
s.Run("DeleteWorkspaceAgentPortShare", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
ws := dbgen.Workspace(s.T(), db, database.Workspace{OwnerID: u.ID})
|
||||
ps := dbgen.WorkspaceAgentPortShare(s.T(), db, database.WorkspaceAgentPortShare{WorkspaceID: ws.ID})
|
||||
check.Args(database.DeleteWorkspaceAgentPortShareParams{
|
||||
WorkspaceID: ps.WorkspaceID,
|
||||
AgentName: ps.AgentName,
|
||||
Port: ps.Port,
|
||||
}).Asserts(ws, rbac.ActionUpdate).Returns()
|
||||
}))
|
||||
}
|
||||
|
||||
func (s *MethodTestSuite) TestExtraMethods() {
|
||||
s.Run("GetProvisionerDaemons", s.Subtest(func(db database.Store, check *expects) {
|
||||
d, err := db.UpsertProvisionerDaemon(context.Background(), database.UpsertProvisionerDaemonParams{
|
||||
|
||||
@@ -90,6 +90,7 @@ func Template(t testing.TB, db database.Store, seed database.Template) database.
|
||||
GroupACL: seed.GroupACL,
|
||||
DisplayName: takeFirst(seed.DisplayName, namesgenerator.GetRandomName(1)),
|
||||
AllowUserCancelWorkspaceJobs: seed.AllowUserCancelWorkspaceJobs,
|
||||
MaxPortSharingLevel: takeFirst(seed.MaxPortSharingLevel, database.AppSharingLevelOwner),
|
||||
})
|
||||
require.NoError(t, err, "insert template")
|
||||
|
||||
@@ -133,6 +134,17 @@ func APIKey(t testing.TB, db database.Store, seed database.APIKey) (key database
|
||||
return key, fmt.Sprintf("%s-%s", key.ID, secret)
|
||||
}
|
||||
|
||||
func WorkspaceAgentPortShare(t testing.TB, db database.Store, orig database.WorkspaceAgentPortShare) database.WorkspaceAgentPortShare {
|
||||
ps, err := db.UpsertWorkspaceAgentPortShare(genCtx, database.UpsertWorkspaceAgentPortShareParams{
|
||||
WorkspaceID: takeFirst(orig.WorkspaceID, uuid.New()),
|
||||
AgentName: takeFirst(orig.AgentName, namesgenerator.GetRandomName(1)),
|
||||
Port: takeFirst(orig.Port, 8080),
|
||||
ShareLevel: takeFirst(orig.ShareLevel, database.AppSharingLevelPublic),
|
||||
})
|
||||
require.NoError(t, err, "insert workspace agent")
|
||||
return ps
|
||||
}
|
||||
|
||||
func WorkspaceAgent(t testing.TB, db database.Store, orig database.WorkspaceAgent) database.WorkspaceAgent {
|
||||
agt, err := db.InsertWorkspaceAgent(genCtx, database.InsertWorkspaceAgentParams{
|
||||
ID: takeFirst(orig.ID, uuid.New()),
|
||||
|
||||
@@ -147,6 +147,7 @@ type data struct {
|
||||
workspaceAgentLogs []database.WorkspaceAgentLog
|
||||
workspaceAgentLogSources []database.WorkspaceAgentLogSource
|
||||
workspaceAgentScripts []database.WorkspaceAgentScript
|
||||
workspaceAgentPortShares []database.WorkspaceAgentPortShare
|
||||
workspaceApps []database.WorkspaceApp
|
||||
workspaceAppStatsLastInsertID int64
|
||||
workspaceAppStats []database.WorkspaceAppStat
|
||||
@@ -1322,6 +1323,25 @@ func (*FakeQuerier) DeleteTailnetTunnel(_ context.Context, arg database.DeleteTa
|
||||
return database.DeleteTailnetTunnelRow{}, ErrUnimplemented
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) DeleteWorkspaceAgentPortShare(_ context.Context, arg database.DeleteWorkspaceAgentPortShareParams) error {
|
||||
err := validateDatabaseType(arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
for i, share := range q.workspaceAgentPortShares {
|
||||
if share.WorkspaceID == arg.WorkspaceID && share.AgentName == arg.AgentName && share.Port == arg.Port {
|
||||
q.workspaceAgentPortShares = append(q.workspaceAgentPortShares[:i], q.workspaceAgentPortShares[i+1:]...)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) FavoriteWorkspace(_ context.Context, arg uuid.UUID) error {
|
||||
err := validateDatabaseType(arg)
|
||||
if err != nil {
|
||||
@@ -4159,6 +4179,24 @@ func (q *FakeQuerier) GetWorkspaceAgentMetadata(_ context.Context, arg database.
|
||||
return metadata, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetWorkspaceAgentPortShare(_ context.Context, arg database.GetWorkspaceAgentPortShareParams) (database.WorkspaceAgentPortShare, error) {
|
||||
err := validateDatabaseType(arg)
|
||||
if err != nil {
|
||||
return database.WorkspaceAgentPortShare{}, err
|
||||
}
|
||||
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
for _, share := range q.workspaceAgentPortShares {
|
||||
if share.WorkspaceID == arg.WorkspaceID && share.AgentName == arg.AgentName && share.Port == arg.Port {
|
||||
return share, nil
|
||||
}
|
||||
}
|
||||
|
||||
return database.WorkspaceAgentPortShare{}, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetWorkspaceAgentScriptsByAgentIDs(_ context.Context, ids []uuid.UUID) ([]database.WorkspaceAgentScript, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
@@ -5374,6 +5412,7 @@ func (q *FakeQuerier) InsertTemplate(_ context.Context, arg database.InsertTempl
|
||||
AllowUserCancelWorkspaceJobs: arg.AllowUserCancelWorkspaceJobs,
|
||||
AllowUserAutostart: true,
|
||||
AllowUserAutostop: true,
|
||||
MaxPortSharingLevel: arg.MaxPortSharingLevel,
|
||||
}
|
||||
q.templates = append(q.templates, template)
|
||||
return nil
|
||||
@@ -6006,6 +6045,20 @@ func (q *FakeQuerier) InsertWorkspaceResourceMetadata(_ context.Context, arg dat
|
||||
return metadata, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) ListWorkspaceAgentPortShares(_ context.Context, workspaceID uuid.UUID) ([]database.WorkspaceAgentPortShare, error) {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
shares := []database.WorkspaceAgentPortShare{}
|
||||
for _, share := range q.workspaceAgentPortShares {
|
||||
if share.WorkspaceID == workspaceID {
|
||||
shares = append(shares, share)
|
||||
}
|
||||
}
|
||||
|
||||
return shares, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) RegisterWorkspaceProxy(_ context.Context, arg database.RegisterWorkspaceProxyParams) (database.WorkspaceProxy, error) {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
@@ -6525,6 +6578,7 @@ func (q *FakeQuerier) UpdateTemplateMetaByID(_ context.Context, arg database.Upd
|
||||
tpl.Icon = arg.Icon
|
||||
tpl.GroupACL = arg.GroupACL
|
||||
tpl.AllowUserCancelWorkspaceJobs = arg.AllowUserCancelWorkspaceJobs
|
||||
tpl.MaxPortSharingLevel = arg.MaxPortSharingLevel
|
||||
q.templates[idx] = tpl
|
||||
return nil
|
||||
}
|
||||
@@ -7515,6 +7569,35 @@ func (*FakeQuerier) UpsertTailnetTunnel(_ context.Context, arg database.UpsertTa
|
||||
return database.TailnetTunnel{}, ErrUnimplemented
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) UpsertWorkspaceAgentPortShare(_ context.Context, arg database.UpsertWorkspaceAgentPortShareParams) (database.WorkspaceAgentPortShare, error) {
|
||||
err := validateDatabaseType(arg)
|
||||
if err != nil {
|
||||
return database.WorkspaceAgentPortShare{}, err
|
||||
}
|
||||
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
for i, share := range q.workspaceAgentPortShares {
|
||||
if share.WorkspaceID == arg.WorkspaceID && share.Port == arg.Port && share.AgentName == arg.AgentName {
|
||||
share.ShareLevel = arg.ShareLevel
|
||||
q.workspaceAgentPortShares[i] = share
|
||||
return share, nil
|
||||
}
|
||||
}
|
||||
|
||||
//nolint:gosimple // casts are not a simplification
|
||||
psl := database.WorkspaceAgentPortShare{
|
||||
WorkspaceID: arg.WorkspaceID,
|
||||
AgentName: arg.AgentName,
|
||||
Port: arg.Port,
|
||||
ShareLevel: arg.ShareLevel,
|
||||
}
|
||||
q.workspaceAgentPortShares = append(q.workspaceAgentPortShares, psl)
|
||||
|
||||
return psl, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetAuthorizedTemplates(ctx context.Context, arg database.GetTemplatesWithFilterParams, prepared rbac.PreparedAuthorized) ([]database.Template, error) {
|
||||
if err := validateDatabaseType(arg); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -300,6 +300,13 @@ func (m metricsStore) DeleteTailnetTunnel(ctx context.Context, arg database.Dele
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m metricsStore) DeleteWorkspaceAgentPortShare(ctx context.Context, arg database.DeleteWorkspaceAgentPortShareParams) error {
|
||||
start := time.Now()
|
||||
r0 := m.s.DeleteWorkspaceAgentPortShare(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("DeleteWorkspaceAgentPortShare").Observe(time.Since(start).Seconds())
|
||||
return r0
|
||||
}
|
||||
|
||||
func (m metricsStore) FavoriteWorkspace(ctx context.Context, arg uuid.UUID) error {
|
||||
start := time.Now()
|
||||
r0 := m.s.FavoriteWorkspace(ctx, arg)
|
||||
@@ -1082,6 +1089,13 @@ func (m metricsStore) GetWorkspaceAgentMetadata(ctx context.Context, workspaceAg
|
||||
return metadata, err
|
||||
}
|
||||
|
||||
func (m metricsStore) GetWorkspaceAgentPortShare(ctx context.Context, arg database.GetWorkspaceAgentPortShareParams) (database.WorkspaceAgentPortShare, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetWorkspaceAgentPortShare(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("GetWorkspaceAgentPortShare").Observe(time.Since(start).Seconds())
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m metricsStore) GetWorkspaceAgentScriptsByAgentIDs(ctx context.Context, ids []uuid.UUID) ([]database.WorkspaceAgentScript, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetWorkspaceAgentScriptsByAgentIDs(ctx, ids)
|
||||
@@ -1607,6 +1621,13 @@ func (m metricsStore) InsertWorkspaceResourceMetadata(ctx context.Context, arg d
|
||||
return metadata, err
|
||||
}
|
||||
|
||||
func (m metricsStore) ListWorkspaceAgentPortShares(ctx context.Context, workspaceID uuid.UUID) ([]database.WorkspaceAgentPortShare, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.ListWorkspaceAgentPortShares(ctx, workspaceID)
|
||||
m.queryLatencies.WithLabelValues("ListWorkspaceAgentPortShares").Observe(time.Since(start).Seconds())
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m metricsStore) RegisterWorkspaceProxy(ctx context.Context, arg database.RegisterWorkspaceProxyParams) (database.WorkspaceProxy, error) {
|
||||
start := time.Now()
|
||||
proxy, err := m.s.RegisterWorkspaceProxy(ctx, arg)
|
||||
@@ -2122,6 +2143,13 @@ func (m metricsStore) UpsertTailnetTunnel(ctx context.Context, arg database.Upse
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m metricsStore) UpsertWorkspaceAgentPortShare(ctx context.Context, arg database.UpsertWorkspaceAgentPortShareParams) (database.WorkspaceAgentPortShare, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.UpsertWorkspaceAgentPortShare(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("UpsertWorkspaceAgentPortShare").Observe(time.Since(start).Seconds())
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m metricsStore) GetAuthorizedTemplates(ctx context.Context, arg database.GetTemplatesWithFilterParams, prepared rbac.PreparedAuthorized) ([]database.Template, error) {
|
||||
start := time.Now()
|
||||
templates, err := m.s.GetAuthorizedTemplates(ctx, arg, prepared)
|
||||
|
||||
@@ -500,6 +500,20 @@ func (mr *MockStoreMockRecorder) DeleteTailnetTunnel(arg0, arg1 any) *gomock.Cal
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTailnetTunnel", reflect.TypeOf((*MockStore)(nil).DeleteTailnetTunnel), arg0, arg1)
|
||||
}
|
||||
|
||||
// DeleteWorkspaceAgentPortShare mocks base method.
|
||||
func (m *MockStore) DeleteWorkspaceAgentPortShare(arg0 context.Context, arg1 database.DeleteWorkspaceAgentPortShareParams) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DeleteWorkspaceAgentPortShare", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// DeleteWorkspaceAgentPortShare indicates an expected call of DeleteWorkspaceAgentPortShare.
|
||||
func (mr *MockStoreMockRecorder) DeleteWorkspaceAgentPortShare(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteWorkspaceAgentPortShare", reflect.TypeOf((*MockStore)(nil).DeleteWorkspaceAgentPortShare), arg0, arg1)
|
||||
}
|
||||
|
||||
// FavoriteWorkspace mocks base method.
|
||||
func (m *MockStore) FavoriteWorkspace(arg0 context.Context, arg1 uuid.UUID) error {
|
||||
m.ctrl.T.Helper()
|
||||
@@ -2254,6 +2268,21 @@ func (mr *MockStoreMockRecorder) GetWorkspaceAgentMetadata(arg0, arg1 any) *gomo
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkspaceAgentMetadata", reflect.TypeOf((*MockStore)(nil).GetWorkspaceAgentMetadata), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetWorkspaceAgentPortShare mocks base method.
|
||||
func (m *MockStore) GetWorkspaceAgentPortShare(arg0 context.Context, arg1 database.GetWorkspaceAgentPortShareParams) (database.WorkspaceAgentPortShare, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetWorkspaceAgentPortShare", arg0, arg1)
|
||||
ret0, _ := ret[0].(database.WorkspaceAgentPortShare)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetWorkspaceAgentPortShare indicates an expected call of GetWorkspaceAgentPortShare.
|
||||
func (mr *MockStoreMockRecorder) GetWorkspaceAgentPortShare(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkspaceAgentPortShare", reflect.TypeOf((*MockStore)(nil).GetWorkspaceAgentPortShare), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetWorkspaceAgentScriptsByAgentIDs mocks base method.
|
||||
func (m *MockStore) GetWorkspaceAgentScriptsByAgentIDs(arg0 context.Context, arg1 []uuid.UUID) ([]database.WorkspaceAgentScript, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@@ -3381,6 +3410,21 @@ func (mr *MockStoreMockRecorder) InsertWorkspaceResourceMetadata(arg0, arg1 any)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertWorkspaceResourceMetadata", reflect.TypeOf((*MockStore)(nil).InsertWorkspaceResourceMetadata), arg0, arg1)
|
||||
}
|
||||
|
||||
// ListWorkspaceAgentPortShares mocks base method.
|
||||
func (m *MockStore) ListWorkspaceAgentPortShares(arg0 context.Context, arg1 uuid.UUID) ([]database.WorkspaceAgentPortShare, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ListWorkspaceAgentPortShares", arg0, arg1)
|
||||
ret0, _ := ret[0].([]database.WorkspaceAgentPortShare)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ListWorkspaceAgentPortShares indicates an expected call of ListWorkspaceAgentPortShares.
|
||||
func (mr *MockStoreMockRecorder) ListWorkspaceAgentPortShares(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListWorkspaceAgentPortShares", reflect.TypeOf((*MockStore)(nil).ListWorkspaceAgentPortShares), arg0, arg1)
|
||||
}
|
||||
|
||||
// Ping mocks base method.
|
||||
func (m *MockStore) Ping(arg0 context.Context) (time.Duration, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@@ -4460,6 +4504,21 @@ func (mr *MockStoreMockRecorder) UpsertTailnetTunnel(arg0, arg1 any) *gomock.Cal
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertTailnetTunnel", reflect.TypeOf((*MockStore)(nil).UpsertTailnetTunnel), arg0, arg1)
|
||||
}
|
||||
|
||||
// UpsertWorkspaceAgentPortShare mocks base method.
|
||||
func (m *MockStore) UpsertWorkspaceAgentPortShare(arg0 context.Context, arg1 database.UpsertWorkspaceAgentPortShareParams) (database.WorkspaceAgentPortShare, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "UpsertWorkspaceAgentPortShare", arg0, arg1)
|
||||
ret0, _ := ret[0].(database.WorkspaceAgentPortShare)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// UpsertWorkspaceAgentPortShare indicates an expected call of UpsertWorkspaceAgentPortShare.
|
||||
func (mr *MockStoreMockRecorder) UpsertWorkspaceAgentPortShare(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertWorkspaceAgentPortShare", reflect.TypeOf((*MockStore)(nil).UpsertWorkspaceAgentPortShare), arg0, arg1)
|
||||
}
|
||||
|
||||
// Wrappers mocks base method.
|
||||
func (m *MockStore) Wrappers() []string {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
Generated
+16
-1
@@ -850,7 +850,8 @@ CREATE TABLE templates (
|
||||
require_active_version boolean DEFAULT false NOT NULL,
|
||||
deprecated text DEFAULT ''::text NOT NULL,
|
||||
use_max_ttl boolean DEFAULT false NOT NULL,
|
||||
activity_bump bigint DEFAULT '3600000000000'::bigint NOT NULL
|
||||
activity_bump bigint DEFAULT '3600000000000'::bigint NOT NULL,
|
||||
max_port_sharing_level app_sharing_level DEFAULT 'owner'::app_sharing_level NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON COLUMN templates.default_ttl IS 'The default duration for autostop for workspaces created from this template.';
|
||||
@@ -901,6 +902,7 @@ CREATE VIEW template_with_users AS
|
||||
templates.deprecated,
|
||||
templates.use_max_ttl,
|
||||
templates.activity_bump,
|
||||
templates.max_port_sharing_level,
|
||||
COALESCE(visible_users.avatar_url, ''::text) AS created_by_avatar_url,
|
||||
COALESCE(visible_users.username, ''::text) AS created_by_username
|
||||
FROM (public.templates
|
||||
@@ -958,6 +960,13 @@ CREATE UNLOGGED TABLE workspace_agent_metadata (
|
||||
|
||||
COMMENT ON COLUMN workspace_agent_metadata.display_order IS 'Specifies the order in which to display agent metadata in user interfaces.';
|
||||
|
||||
CREATE TABLE workspace_agent_port_share (
|
||||
workspace_id uuid NOT NULL,
|
||||
agent_name text NOT NULL,
|
||||
port integer NOT NULL,
|
||||
share_level app_sharing_level NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE workspace_agent_scripts (
|
||||
workspace_agent_id uuid NOT NULL,
|
||||
log_source_id uuid NOT NULL,
|
||||
@@ -1405,6 +1414,9 @@ ALTER TABLE ONLY workspace_agent_log_sources
|
||||
ALTER TABLE ONLY workspace_agent_metadata
|
||||
ADD CONSTRAINT workspace_agent_metadata_pkey PRIMARY KEY (workspace_agent_id, key);
|
||||
|
||||
ALTER TABLE ONLY workspace_agent_port_share
|
||||
ADD CONSTRAINT workspace_agent_port_share_pkey PRIMARY KEY (workspace_id, agent_name, port);
|
||||
|
||||
ALTER TABLE ONLY workspace_agent_logs
|
||||
ADD CONSTRAINT workspace_agent_startup_logs_pkey PRIMARY KEY (id);
|
||||
|
||||
@@ -1631,6 +1643,9 @@ ALTER TABLE ONLY workspace_agent_log_sources
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ const (
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
DROP TABLE workspace_agent_port_share;
|
||||
DROP VIEW template_with_users;
|
||||
ALTER TABLE templates DROP COLUMN max_port_sharing_level;
|
||||
|
||||
-- Update the template_with_users view by recreating it.
|
||||
|
||||
CREATE VIEW
|
||||
template_with_users
|
||||
AS
|
||||
SELECT
|
||||
templates.*,
|
||||
coalesce(visible_users.avatar_url, '') AS created_by_avatar_url,
|
||||
coalesce(visible_users.username, '') AS created_by_username
|
||||
FROM
|
||||
templates
|
||||
LEFT JOIN
|
||||
visible_users
|
||||
ON
|
||||
templates.created_by = visible_users.id;
|
||||
COMMENT ON VIEW template_with_users IS 'Joins in the username + avatar url of the created by user.';
|
||||
@@ -0,0 +1,27 @@
|
||||
CREATE TABLE workspace_agent_port_share (
|
||||
workspace_id uuid NOT NULL REFERENCES workspaces (id) ON DELETE CASCADE,
|
||||
agent_name text NOT NULL,
|
||||
port integer NOT NULL,
|
||||
share_level app_sharing_level NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE workspace_agent_port_share ADD PRIMARY KEY (workspace_id, agent_name, port);
|
||||
|
||||
ALTER TABLE templates ADD COLUMN max_port_sharing_level app_sharing_level NOT NULL DEFAULT 'owner'::app_sharing_level;
|
||||
|
||||
-- Update the template_with_users view by recreating it.
|
||||
DROP VIEW template_with_users;
|
||||
CREATE VIEW
|
||||
template_with_users
|
||||
AS
|
||||
SELECT
|
||||
templates.*,
|
||||
coalesce(visible_users.avatar_url, '') AS created_by_avatar_url,
|
||||
coalesce(visible_users.username, '') AS created_by_username
|
||||
FROM
|
||||
templates
|
||||
LEFT JOIN
|
||||
visible_users
|
||||
ON
|
||||
templates.created_by = visible_users.id;
|
||||
COMMENT ON VIEW template_with_users IS 'Joins in the username + avatar url of the created by user.';
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
INSERT INTO workspace_agent_port_share
|
||||
(workspace_id, agent_name, port, share_level)
|
||||
VALUES
|
||||
('b90547be-8870-4d68-8184-e8b2242b7c01', 'qua', 8080, 'public'::app_sharing_level) RETURNING *;
|
||||
@@ -91,6 +91,7 @@ func (q *sqlQuerier) GetAuthorizedTemplates(ctx context.Context, arg GetTemplate
|
||||
&i.Deprecated,
|
||||
&i.UseMaxTtl,
|
||||
&i.ActivityBump,
|
||||
&i.MaxPortSharingLevel,
|
||||
&i.CreatedByAvatarURL,
|
||||
&i.CreatedByUsername,
|
||||
); err != nil {
|
||||
|
||||
@@ -2004,6 +2004,7 @@ type Template struct {
|
||||
Deprecated string `db:"deprecated" json:"deprecated"`
|
||||
UseMaxTtl bool `db:"use_max_ttl" json:"use_max_ttl"`
|
||||
ActivityBump int64 `db:"activity_bump" json:"activity_bump"`
|
||||
MaxPortSharingLevel AppSharingLevel `db:"max_port_sharing_level" json:"max_port_sharing_level"`
|
||||
CreatedByAvatarURL string `db:"created_by_avatar_url" json:"created_by_avatar_url"`
|
||||
CreatedByUsername string `db:"created_by_username" json:"created_by_username"`
|
||||
}
|
||||
@@ -2044,9 +2045,10 @@ type TemplateTable struct {
|
||||
AutostartBlockDaysOfWeek int16 `db:"autostart_block_days_of_week" json:"autostart_block_days_of_week"`
|
||||
RequireActiveVersion bool `db:"require_active_version" json:"require_active_version"`
|
||||
// If set to a non empty string, the template will no longer be able to be used. The message will be displayed to the user.
|
||||
Deprecated string `db:"deprecated" json:"deprecated"`
|
||||
UseMaxTtl bool `db:"use_max_ttl" json:"use_max_ttl"`
|
||||
ActivityBump int64 `db:"activity_bump" json:"activity_bump"`
|
||||
Deprecated string `db:"deprecated" json:"deprecated"`
|
||||
UseMaxTtl bool `db:"use_max_ttl" json:"use_max_ttl"`
|
||||
ActivityBump int64 `db:"activity_bump" json:"activity_bump"`
|
||||
MaxPortSharingLevel AppSharingLevel `db:"max_port_sharing_level" json:"max_port_sharing_level"`
|
||||
}
|
||||
|
||||
// Joins in the username + avatar url of the created by user.
|
||||
@@ -2274,6 +2276,13 @@ type WorkspaceAgentMetadatum struct {
|
||||
DisplayOrder int32 `db:"display_order" json:"display_order"`
|
||||
}
|
||||
|
||||
type WorkspaceAgentPortShare struct {
|
||||
WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
|
||||
AgentName string `db:"agent_name" json:"agent_name"`
|
||||
Port int32 `db:"port" json:"port"`
|
||||
ShareLevel AppSharingLevel `db:"share_level" json:"share_level"`
|
||||
}
|
||||
|
||||
type WorkspaceAgentScript struct {
|
||||
WorkspaceAgentID uuid.UUID `db:"workspace_agent_id" json:"workspace_agent_id"`
|
||||
LogSourceID uuid.UUID `db:"log_source_id" json:"log_source_id"`
|
||||
|
||||
@@ -77,6 +77,7 @@ type sqlcQuerier interface {
|
||||
DeleteTailnetClientSubscription(ctx context.Context, arg DeleteTailnetClientSubscriptionParams) error
|
||||
DeleteTailnetPeer(ctx context.Context, arg DeleteTailnetPeerParams) (DeleteTailnetPeerRow, error)
|
||||
DeleteTailnetTunnel(ctx context.Context, arg DeleteTailnetTunnelParams) (DeleteTailnetTunnelRow, error)
|
||||
DeleteWorkspaceAgentPortShare(ctx context.Context, arg DeleteWorkspaceAgentPortShareParams) error
|
||||
FavoriteWorkspace(ctx context.Context, id uuid.UUID) error
|
||||
GetAPIKeyByID(ctx context.Context, id string) (APIKey, error)
|
||||
// there is no unique constraint on empty token names
|
||||
@@ -227,6 +228,7 @@ type sqlcQuerier interface {
|
||||
GetWorkspaceAgentLogSourcesByAgentIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceAgentLogSource, error)
|
||||
GetWorkspaceAgentLogsAfter(ctx context.Context, arg GetWorkspaceAgentLogsAfterParams) ([]WorkspaceAgentLog, error)
|
||||
GetWorkspaceAgentMetadata(ctx context.Context, arg GetWorkspaceAgentMetadataParams) ([]WorkspaceAgentMetadatum, error)
|
||||
GetWorkspaceAgentPortShare(ctx context.Context, arg GetWorkspaceAgentPortShareParams) (WorkspaceAgentPortShare, error)
|
||||
GetWorkspaceAgentScriptsByAgentIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceAgentScript, error)
|
||||
GetWorkspaceAgentStats(ctx context.Context, createdAt time.Time) ([]GetWorkspaceAgentStatsRow, error)
|
||||
GetWorkspaceAgentStatsAndLabels(ctx context.Context, createdAt time.Time) ([]GetWorkspaceAgentStatsAndLabelsRow, error)
|
||||
@@ -317,6 +319,7 @@ type sqlcQuerier interface {
|
||||
InsertWorkspaceProxy(ctx context.Context, arg InsertWorkspaceProxyParams) (WorkspaceProxy, error)
|
||||
InsertWorkspaceResource(ctx context.Context, arg InsertWorkspaceResourceParams) (WorkspaceResource, error)
|
||||
InsertWorkspaceResourceMetadata(ctx context.Context, arg InsertWorkspaceResourceMetadataParams) ([]WorkspaceResourceMetadatum, error)
|
||||
ListWorkspaceAgentPortShares(ctx context.Context, workspaceID uuid.UUID) ([]WorkspaceAgentPortShare, error)
|
||||
RegisterWorkspaceProxy(ctx context.Context, arg RegisterWorkspaceProxyParams) (WorkspaceProxy, error)
|
||||
RevokeDBCryptKey(ctx context.Context, activeKeyDigest string) error
|
||||
// Non blocking lock. Returns true if the lock was acquired, false otherwise.
|
||||
@@ -400,6 +403,7 @@ type sqlcQuerier interface {
|
||||
UpsertTailnetCoordinator(ctx context.Context, id uuid.UUID) (TailnetCoordinator, error)
|
||||
UpsertTailnetPeer(ctx context.Context, arg UpsertTailnetPeerParams) (TailnetPeer, error)
|
||||
UpsertTailnetTunnel(ctx context.Context, arg UpsertTailnetTunnelParams) (TailnetTunnel, error)
|
||||
UpsertWorkspaceAgentPortShare(ctx context.Context, arg UpsertWorkspaceAgentPortShareParams) (WorkspaceAgentPortShare, error)
|
||||
}
|
||||
|
||||
var _ sqlcQuerier = (*sqlQuerier)(nil)
|
||||
|
||||
+125
-16
@@ -5728,7 +5728,7 @@ func (q *sqlQuerier) GetTemplateAverageBuildTime(ctx context.Context, arg GetTem
|
||||
|
||||
const getTemplateByID = `-- name: GetTemplateByID :one
|
||||
SELECT
|
||||
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, max_ttl, 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, use_max_ttl, activity_bump, created_by_avatar_url, created_by_username
|
||||
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, max_ttl, 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, use_max_ttl, activity_bump, max_port_sharing_level, created_by_avatar_url, created_by_username
|
||||
FROM
|
||||
template_with_users
|
||||
WHERE
|
||||
@@ -5770,6 +5770,7 @@ func (q *sqlQuerier) GetTemplateByID(ctx context.Context, id uuid.UUID) (Templat
|
||||
&i.Deprecated,
|
||||
&i.UseMaxTtl,
|
||||
&i.ActivityBump,
|
||||
&i.MaxPortSharingLevel,
|
||||
&i.CreatedByAvatarURL,
|
||||
&i.CreatedByUsername,
|
||||
)
|
||||
@@ -5778,7 +5779,7 @@ func (q *sqlQuerier) GetTemplateByID(ctx context.Context, id uuid.UUID) (Templat
|
||||
|
||||
const getTemplateByOrganizationAndName = `-- name: GetTemplateByOrganizationAndName :one
|
||||
SELECT
|
||||
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, max_ttl, 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, use_max_ttl, activity_bump, created_by_avatar_url, created_by_username
|
||||
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, max_ttl, 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, use_max_ttl, activity_bump, max_port_sharing_level, created_by_avatar_url, created_by_username
|
||||
FROM
|
||||
template_with_users AS templates
|
||||
WHERE
|
||||
@@ -5828,6 +5829,7 @@ func (q *sqlQuerier) GetTemplateByOrganizationAndName(ctx context.Context, arg G
|
||||
&i.Deprecated,
|
||||
&i.UseMaxTtl,
|
||||
&i.ActivityBump,
|
||||
&i.MaxPortSharingLevel,
|
||||
&i.CreatedByAvatarURL,
|
||||
&i.CreatedByUsername,
|
||||
)
|
||||
@@ -5835,7 +5837,7 @@ func (q *sqlQuerier) GetTemplateByOrganizationAndName(ctx context.Context, arg G
|
||||
}
|
||||
|
||||
const getTemplates = `-- name: GetTemplates :many
|
||||
SELECT 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, max_ttl, 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, use_max_ttl, activity_bump, created_by_avatar_url, created_by_username FROM template_with_users AS templates
|
||||
SELECT 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, max_ttl, 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, use_max_ttl, activity_bump, max_port_sharing_level, created_by_avatar_url, created_by_username FROM template_with_users AS templates
|
||||
ORDER BY (name, id) ASC
|
||||
`
|
||||
|
||||
@@ -5878,6 +5880,7 @@ func (q *sqlQuerier) GetTemplates(ctx context.Context) ([]Template, error) {
|
||||
&i.Deprecated,
|
||||
&i.UseMaxTtl,
|
||||
&i.ActivityBump,
|
||||
&i.MaxPortSharingLevel,
|
||||
&i.CreatedByAvatarURL,
|
||||
&i.CreatedByUsername,
|
||||
); err != nil {
|
||||
@@ -5896,7 +5899,7 @@ func (q *sqlQuerier) GetTemplates(ctx context.Context) ([]Template, error) {
|
||||
|
||||
const getTemplatesWithFilter = `-- name: GetTemplatesWithFilter :many
|
||||
SELECT
|
||||
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, max_ttl, 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, use_max_ttl, activity_bump, created_by_avatar_url, created_by_username
|
||||
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, max_ttl, 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, use_max_ttl, activity_bump, max_port_sharing_level, created_by_avatar_url, created_by_username
|
||||
FROM
|
||||
template_with_users AS templates
|
||||
WHERE
|
||||
@@ -5989,6 +5992,7 @@ func (q *sqlQuerier) GetTemplatesWithFilter(ctx context.Context, arg GetTemplate
|
||||
&i.Deprecated,
|
||||
&i.UseMaxTtl,
|
||||
&i.ActivityBump,
|
||||
&i.MaxPortSharingLevel,
|
||||
&i.CreatedByAvatarURL,
|
||||
&i.CreatedByUsername,
|
||||
); err != nil {
|
||||
@@ -6021,10 +6025,11 @@ INSERT INTO
|
||||
user_acl,
|
||||
group_acl,
|
||||
display_name,
|
||||
allow_user_cancel_workspace_jobs
|
||||
allow_user_cancel_workspace_jobs,
|
||||
max_port_sharing_level
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
|
||||
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)
|
||||
`
|
||||
|
||||
type InsertTemplateParams struct {
|
||||
@@ -6042,6 +6047,7 @@ type InsertTemplateParams struct {
|
||||
GroupACL TemplateACL `db:"group_acl" json:"group_acl"`
|
||||
DisplayName string `db:"display_name" json:"display_name"`
|
||||
AllowUserCancelWorkspaceJobs bool `db:"allow_user_cancel_workspace_jobs" json:"allow_user_cancel_workspace_jobs"`
|
||||
MaxPortSharingLevel AppSharingLevel `db:"max_port_sharing_level" json:"max_port_sharing_level"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) InsertTemplate(ctx context.Context, arg InsertTemplateParams) error {
|
||||
@@ -6060,6 +6066,7 @@ func (q *sqlQuerier) InsertTemplate(ctx context.Context, arg InsertTemplateParam
|
||||
arg.GroupACL,
|
||||
arg.DisplayName,
|
||||
arg.AllowUserCancelWorkspaceJobs,
|
||||
arg.MaxPortSharingLevel,
|
||||
)
|
||||
return err
|
||||
}
|
||||
@@ -6158,20 +6165,22 @@ SET
|
||||
icon = $5,
|
||||
display_name = $6,
|
||||
allow_user_cancel_workspace_jobs = $7,
|
||||
group_acl = $8
|
||||
group_acl = $8,
|
||||
max_port_sharing_level = $9
|
||||
WHERE
|
||||
id = $1
|
||||
`
|
||||
|
||||
type UpdateTemplateMetaByIDParams struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
Description string `db:"description" json:"description"`
|
||||
Name string `db:"name" json:"name"`
|
||||
Icon string `db:"icon" json:"icon"`
|
||||
DisplayName string `db:"display_name" json:"display_name"`
|
||||
AllowUserCancelWorkspaceJobs bool `db:"allow_user_cancel_workspace_jobs" json:"allow_user_cancel_workspace_jobs"`
|
||||
GroupACL TemplateACL `db:"group_acl" json:"group_acl"`
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
Description string `db:"description" json:"description"`
|
||||
Name string `db:"name" json:"name"`
|
||||
Icon string `db:"icon" json:"icon"`
|
||||
DisplayName string `db:"display_name" json:"display_name"`
|
||||
AllowUserCancelWorkspaceJobs bool `db:"allow_user_cancel_workspace_jobs" json:"allow_user_cancel_workspace_jobs"`
|
||||
GroupACL TemplateACL `db:"group_acl" json:"group_acl"`
|
||||
MaxPortSharingLevel AppSharingLevel `db:"max_port_sharing_level" json:"max_port_sharing_level"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) UpdateTemplateMetaByID(ctx context.Context, arg UpdateTemplateMetaByIDParams) error {
|
||||
@@ -6184,6 +6193,7 @@ func (q *sqlQuerier) UpdateTemplateMetaByID(ctx context.Context, arg UpdateTempl
|
||||
arg.DisplayName,
|
||||
arg.AllowUserCancelWorkspaceJobs,
|
||||
arg.GroupACL,
|
||||
arg.MaxPortSharingLevel,
|
||||
)
|
||||
return err
|
||||
}
|
||||
@@ -8141,6 +8151,105 @@ func (q *sqlQuerier) UpdateUserStatus(ctx context.Context, arg UpdateUserStatusP
|
||||
return i, err
|
||||
}
|
||||
|
||||
const deleteWorkspaceAgentPortShare = `-- name: DeleteWorkspaceAgentPortShare :exec
|
||||
DELETE FROM workspace_agent_port_share WHERE workspace_id = $1 AND agent_name = $2 AND port = $3
|
||||
`
|
||||
|
||||
type DeleteWorkspaceAgentPortShareParams struct {
|
||||
WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
|
||||
AgentName string `db:"agent_name" json:"agent_name"`
|
||||
Port int32 `db:"port" json:"port"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) DeleteWorkspaceAgentPortShare(ctx context.Context, arg DeleteWorkspaceAgentPortShareParams) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteWorkspaceAgentPortShare, arg.WorkspaceID, arg.AgentName, arg.Port)
|
||||
return err
|
||||
}
|
||||
|
||||
const getWorkspaceAgentPortShare = `-- name: GetWorkspaceAgentPortShare :one
|
||||
SELECT workspace_id, agent_name, port, share_level FROM workspace_agent_port_share WHERE workspace_id = $1 AND agent_name = $2 AND port = $3
|
||||
`
|
||||
|
||||
type GetWorkspaceAgentPortShareParams struct {
|
||||
WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
|
||||
AgentName string `db:"agent_name" json:"agent_name"`
|
||||
Port int32 `db:"port" json:"port"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) GetWorkspaceAgentPortShare(ctx context.Context, arg GetWorkspaceAgentPortShareParams) (WorkspaceAgentPortShare, error) {
|
||||
row := q.db.QueryRowContext(ctx, getWorkspaceAgentPortShare, arg.WorkspaceID, arg.AgentName, arg.Port)
|
||||
var i WorkspaceAgentPortShare
|
||||
err := row.Scan(
|
||||
&i.WorkspaceID,
|
||||
&i.AgentName,
|
||||
&i.Port,
|
||||
&i.ShareLevel,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const listWorkspaceAgentPortShares = `-- name: ListWorkspaceAgentPortShares :many
|
||||
SELECT workspace_id, agent_name, port, share_level FROM workspace_agent_port_share WHERE workspace_id = $1
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) ListWorkspaceAgentPortShares(ctx context.Context, workspaceID uuid.UUID) ([]WorkspaceAgentPortShare, error) {
|
||||
rows, err := q.db.QueryContext(ctx, listWorkspaceAgentPortShares, workspaceID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []WorkspaceAgentPortShare
|
||||
for rows.Next() {
|
||||
var i WorkspaceAgentPortShare
|
||||
if err := rows.Scan(
|
||||
&i.WorkspaceID,
|
||||
&i.AgentName,
|
||||
&i.Port,
|
||||
&i.ShareLevel,
|
||||
); 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 upsertWorkspaceAgentPortShare = `-- name: UpsertWorkspaceAgentPortShare :one
|
||||
INSERT INTO workspace_agent_port_share (workspace_id, agent_name, port, share_level)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
ON CONFLICT (workspace_id, agent_name, port) DO UPDATE SET share_level = $4 RETURNING workspace_id, agent_name, port, share_level
|
||||
`
|
||||
|
||||
type UpsertWorkspaceAgentPortShareParams struct {
|
||||
WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
|
||||
AgentName string `db:"agent_name" json:"agent_name"`
|
||||
Port int32 `db:"port" json:"port"`
|
||||
ShareLevel AppSharingLevel `db:"share_level" json:"share_level"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) UpsertWorkspaceAgentPortShare(ctx context.Context, arg UpsertWorkspaceAgentPortShareParams) (WorkspaceAgentPortShare, error) {
|
||||
row := q.db.QueryRowContext(ctx, upsertWorkspaceAgentPortShare,
|
||||
arg.WorkspaceID,
|
||||
arg.AgentName,
|
||||
arg.Port,
|
||||
arg.ShareLevel,
|
||||
)
|
||||
var i WorkspaceAgentPortShare
|
||||
err := row.Scan(
|
||||
&i.WorkspaceID,
|
||||
&i.AgentName,
|
||||
&i.Port,
|
||||
&i.ShareLevel,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const deleteOldWorkspaceAgentLogs = `-- name: DeleteOldWorkspaceAgentLogs :exec
|
||||
DELETE FROM workspace_agent_logs WHERE agent_id IN
|
||||
(SELECT id FROM workspace_agents WHERE last_connected_at IS NOT NULL
|
||||
@@ -11378,7 +11487,7 @@ LEFT JOIN LATERAL (
|
||||
) latest_build ON TRUE
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT
|
||||
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, max_ttl, 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, use_max_ttl, activity_bump
|
||||
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, max_ttl, 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, use_max_ttl, activity_bump, max_port_sharing_level
|
||||
FROM
|
||||
templates
|
||||
WHERE
|
||||
|
||||
@@ -83,10 +83,11 @@ INSERT INTO
|
||||
user_acl,
|
||||
group_acl,
|
||||
display_name,
|
||||
allow_user_cancel_workspace_jobs
|
||||
allow_user_cancel_workspace_jobs,
|
||||
max_port_sharing_level
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14);
|
||||
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15);
|
||||
|
||||
-- name: UpdateTemplateActiveVersionByID :exec
|
||||
UPDATE
|
||||
@@ -116,7 +117,8 @@ SET
|
||||
icon = $5,
|
||||
display_name = $6,
|
||||
allow_user_cancel_workspace_jobs = $7,
|
||||
group_acl = $8
|
||||
group_acl = $8,
|
||||
max_port_sharing_level = $9
|
||||
WHERE
|
||||
id = $1
|
||||
;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
-- name: GetWorkspaceAgentPortShare :one
|
||||
SELECT * FROM workspace_agent_port_share WHERE workspace_id = $1 AND agent_name = $2 AND port = $3;
|
||||
|
||||
-- name: ListWorkspaceAgentPortShares :many
|
||||
SELECT * FROM workspace_agent_port_share WHERE workspace_id = $1;
|
||||
|
||||
-- name: DeleteWorkspaceAgentPortShare :exec
|
||||
DELETE FROM workspace_agent_port_share WHERE workspace_id = $1 AND agent_name = $2 AND port = $3;
|
||||
|
||||
-- name: UpsertWorkspaceAgentPortShare :one
|
||||
INSERT INTO workspace_agent_port_share (workspace_id, agent_name, port, share_level)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
ON CONFLICT (workspace_id, agent_name, port) DO UPDATE SET share_level = $4 RETURNING *;
|
||||
@@ -51,6 +51,7 @@ const (
|
||||
UniqueUsersPkey UniqueConstraint = "users_pkey" // ALTER TABLE ONLY users ADD CONSTRAINT users_pkey PRIMARY KEY (id);
|
||||
UniqueWorkspaceAgentLogSourcesPkey UniqueConstraint = "workspace_agent_log_sources_pkey" // ALTER TABLE ONLY workspace_agent_log_sources ADD CONSTRAINT workspace_agent_log_sources_pkey PRIMARY KEY (workspace_agent_id, id);
|
||||
UniqueWorkspaceAgentMetadataPkey UniqueConstraint = "workspace_agent_metadata_pkey" // ALTER TABLE ONLY workspace_agent_metadata ADD CONSTRAINT workspace_agent_metadata_pkey PRIMARY KEY (workspace_agent_id, key);
|
||||
UniqueWorkspaceAgentPortSharePkey UniqueConstraint = "workspace_agent_port_share_pkey" // ALTER TABLE ONLY workspace_agent_port_share ADD CONSTRAINT workspace_agent_port_share_pkey PRIMARY KEY (workspace_id, agent_name, port);
|
||||
UniqueWorkspaceAgentStartupLogsPkey UniqueConstraint = "workspace_agent_startup_logs_pkey" // ALTER TABLE ONLY workspace_agent_logs ADD CONSTRAINT workspace_agent_startup_logs_pkey PRIMARY KEY (id);
|
||||
UniqueWorkspaceAgentsPkey UniqueConstraint = "workspace_agents_pkey" // ALTER TABLE ONLY workspace_agents ADD CONSTRAINT workspace_agents_pkey PRIMARY KEY (id);
|
||||
UniqueWorkspaceAppStatsPkey UniqueConstraint = "workspace_app_stats_pkey" // ALTER TABLE ONLY workspace_app_stats ADD CONSTRAINT workspace_app_stats_pkey PRIMARY KEY (id);
|
||||
|
||||
Reference in New Issue
Block a user