mirror of
https://github.com/coder/coder.git
synced 2025-07-06 15:41:45 +00:00
feat: get org scoped provisioners (#13953)
This commit is contained in:
@ -1627,6 +1627,10 @@ func (q *querier) GetProvisionerDaemons(ctx context.Context) ([]database.Provisi
|
||||
return fetchWithPostFilter(q.auth, policy.ActionRead, fetch)(ctx, nil)
|
||||
}
|
||||
|
||||
func (q *querier) GetProvisionerDaemonsByOrganization(ctx context.Context, organizationID uuid.UUID) ([]database.ProvisionerDaemon, error) {
|
||||
return fetchWithPostFilter(q.auth, policy.ActionRead, q.db.GetProvisionerDaemonsByOrganization)(ctx, organizationID)
|
||||
}
|
||||
|
||||
func (q *querier) GetProvisionerJobByID(ctx context.Context, id uuid.UUID) (database.ProvisionerJob, error) {
|
||||
job, err := q.db.GetProvisionerJobByID(ctx, id)
|
||||
if err != nil {
|
||||
@ -3727,7 +3731,7 @@ func (q *querier) UpsertOAuthSigningKey(ctx context.Context, value string) error
|
||||
}
|
||||
|
||||
func (q *querier) UpsertProvisionerDaemon(ctx context.Context, arg database.UpsertProvisionerDaemonParams) (database.ProvisionerDaemon, error) {
|
||||
res := rbac.ResourceProvisionerDaemon.All()
|
||||
res := rbac.ResourceProvisionerDaemon.InOrg(arg.OrganizationID)
|
||||
if arg.Tags[provisionersdk.TagScope] == provisionersdk.ScopeUser {
|
||||
res.Owner = arg.Tags[provisionersdk.TagOwner]
|
||||
}
|
||||
|
@ -1863,6 +1863,19 @@ func (s *MethodTestSuite) TestExtraMethods() {
|
||||
s.NoError(err, "insert provisioner daemon")
|
||||
check.Args().Asserts(d, policy.ActionRead)
|
||||
}))
|
||||
s.Run("GetProvisionerDaemonsByOrganization", s.Subtest(func(db database.Store, check *expects) {
|
||||
org := dbgen.Organization(s.T(), db, database.Organization{})
|
||||
d, err := db.UpsertProvisionerDaemon(context.Background(), database.UpsertProvisionerDaemonParams{
|
||||
OrganizationID: org.ID,
|
||||
Tags: database.StringMap(map[string]string{
|
||||
provisionersdk.TagScope: provisionersdk.ScopeOrganization,
|
||||
}),
|
||||
})
|
||||
s.NoError(err, "insert provisioner daemon")
|
||||
ds, err := db.GetProvisionerDaemonsByOrganization(context.Background(), org.ID)
|
||||
s.NoError(err, "get provisioner daemon by org")
|
||||
check.Args(org.ID).Asserts(d, policy.ActionRead).Returns(ds)
|
||||
}))
|
||||
s.Run("DeleteOldProvisionerDaemons", s.Subtest(func(db database.Store, check *expects) {
|
||||
_, err := db.UpsertProvisionerDaemon(context.Background(), database.UpsertProvisionerDaemonParams{
|
||||
Tags: database.StringMap(map[string]string{
|
||||
@ -2328,13 +2341,16 @@ func (s *MethodTestSuite) TestSystemFunctions() {
|
||||
}).Asserts( /*rbac.ResourceSystem, policy.ActionCreate*/ )
|
||||
}))
|
||||
s.Run("UpsertProvisionerDaemon", s.Subtest(func(db database.Store, check *expects) {
|
||||
pd := rbac.ResourceProvisionerDaemon.All()
|
||||
org := dbgen.Organization(s.T(), db, database.Organization{})
|
||||
pd := rbac.ResourceProvisionerDaemon.InOrg(org.ID)
|
||||
check.Args(database.UpsertProvisionerDaemonParams{
|
||||
OrganizationID: org.ID,
|
||||
Tags: database.StringMap(map[string]string{
|
||||
provisionersdk.TagScope: provisionersdk.ScopeOrganization,
|
||||
}),
|
||||
}).Asserts(pd, policy.ActionCreate)
|
||||
check.Args(database.UpsertProvisionerDaemonParams{
|
||||
OrganizationID: org.ID,
|
||||
Tags: database.StringMap(map[string]string{
|
||||
provisionersdk.TagScope: provisionersdk.ScopeUser,
|
||||
provisionersdk.TagOwner: "11111111-1111-1111-1111-111111111111",
|
||||
|
@ -3140,6 +3140,21 @@ func (q *FakeQuerier) GetProvisionerDaemons(_ context.Context) ([]database.Provi
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetProvisionerDaemonsByOrganization(_ context.Context, organizationID uuid.UUID) ([]database.ProvisionerDaemon, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
daemons := make([]database.ProvisionerDaemon, 0)
|
||||
for _, daemon := range q.provisionerDaemons {
|
||||
if daemon.OrganizationID == organizationID {
|
||||
daemon.Tags = maps.Clone(daemon.Tags)
|
||||
daemons = append(daemons, daemon)
|
||||
}
|
||||
}
|
||||
|
||||
return daemons, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetProvisionerJobByID(ctx context.Context, id uuid.UUID) (database.ProvisionerJob, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
@ -879,6 +879,13 @@ func (m metricsStore) GetProvisionerDaemons(ctx context.Context) ([]database.Pro
|
||||
return daemons, err
|
||||
}
|
||||
|
||||
func (m metricsStore) GetProvisionerDaemonsByOrganization(ctx context.Context, organizationID uuid.UUID) ([]database.ProvisionerDaemon, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetProvisionerDaemonsByOrganization(ctx, organizationID)
|
||||
m.queryLatencies.WithLabelValues("GetProvisionerDaemonsByOrganization").Observe(time.Since(start).Seconds())
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m metricsStore) GetProvisionerJobByID(ctx context.Context, id uuid.UUID) (database.ProvisionerJob, error) {
|
||||
start := time.Now()
|
||||
job, err := m.s.GetProvisionerJobByID(ctx, id)
|
||||
|
@ -1765,6 +1765,21 @@ func (mr *MockStoreMockRecorder) GetProvisionerDaemons(arg0 any) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProvisionerDaemons", reflect.TypeOf((*MockStore)(nil).GetProvisionerDaemons), arg0)
|
||||
}
|
||||
|
||||
// GetProvisionerDaemonsByOrganization mocks base method.
|
||||
func (m *MockStore) GetProvisionerDaemonsByOrganization(arg0 context.Context, arg1 uuid.UUID) ([]database.ProvisionerDaemon, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetProvisionerDaemonsByOrganization", arg0, arg1)
|
||||
ret0, _ := ret[0].([]database.ProvisionerDaemon)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetProvisionerDaemonsByOrganization indicates an expected call of GetProvisionerDaemonsByOrganization.
|
||||
func (mr *MockStoreMockRecorder) GetProvisionerDaemonsByOrganization(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProvisionerDaemonsByOrganization", reflect.TypeOf((*MockStore)(nil).GetProvisionerDaemonsByOrganization), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetProvisionerJobByID mocks base method.
|
||||
func (m *MockStore) GetProvisionerJobByID(arg0 context.Context, arg1 uuid.UUID) (database.ProvisionerJob, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
@ -209,7 +209,9 @@ func (o Organization) RBACObject() rbac.Object {
|
||||
}
|
||||
|
||||
func (p ProvisionerDaemon) RBACObject() rbac.Object {
|
||||
return rbac.ResourceProvisionerDaemon.WithID(p.ID)
|
||||
return rbac.ResourceProvisionerDaemon.
|
||||
WithID(p.ID).
|
||||
InOrg(p.OrganizationID)
|
||||
}
|
||||
|
||||
func (p ProvisionerKey) RBACObject() rbac.Object {
|
||||
|
@ -181,6 +181,7 @@ type sqlcQuerier interface {
|
||||
GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUID) ([]ParameterSchema, error)
|
||||
GetPreviousTemplateVersion(ctx context.Context, arg GetPreviousTemplateVersionParams) (TemplateVersion, error)
|
||||
GetProvisionerDaemons(ctx context.Context) ([]ProvisionerDaemon, error)
|
||||
GetProvisionerDaemonsByOrganization(ctx context.Context, organizationID uuid.UUID) ([]ProvisionerDaemon, error)
|
||||
GetProvisionerJobByID(ctx context.Context, id uuid.UUID) (ProvisionerJob, error)
|
||||
GetProvisionerJobsByIDs(ctx context.Context, ids []uuid.UUID) ([]ProvisionerJob, error)
|
||||
GetProvisionerJobsByIDsWithQueuePosition(ctx context.Context, ids []uuid.UUID) ([]GetProvisionerJobsByIDsWithQueuePositionRow, error)
|
||||
|
@ -4770,6 +4770,49 @@ func (q *sqlQuerier) GetProvisionerDaemons(ctx context.Context) ([]ProvisionerDa
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getProvisionerDaemonsByOrganization = `-- name: GetProvisionerDaemonsByOrganization :many
|
||||
SELECT
|
||||
id, created_at, name, provisioners, replica_id, tags, last_seen_at, version, api_version, organization_id
|
||||
FROM
|
||||
provisioner_daemons
|
||||
WHERE
|
||||
organization_id = $1
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetProvisionerDaemonsByOrganization(ctx context.Context, organizationID uuid.UUID) ([]ProvisionerDaemon, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getProvisionerDaemonsByOrganization, organizationID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []ProvisionerDaemon
|
||||
for rows.Next() {
|
||||
var i ProvisionerDaemon
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
pq.Array(&i.Provisioners),
|
||||
&i.ReplicaID,
|
||||
&i.Tags,
|
||||
&i.LastSeenAt,
|
||||
&i.Version,
|
||||
&i.APIVersion,
|
||||
&i.OrganizationID,
|
||||
); 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 updateProvisionerDaemonLastSeenAt = `-- name: UpdateProvisionerDaemonLastSeenAt :exec
|
||||
UPDATE provisioner_daemons
|
||||
SET
|
||||
|
@ -4,6 +4,14 @@ SELECT
|
||||
FROM
|
||||
provisioner_daemons;
|
||||
|
||||
-- name: GetProvisionerDaemonsByOrganization :many
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
provisioner_daemons
|
||||
WHERE
|
||||
organization_id = @organization_id;
|
||||
|
||||
-- name: DeleteOldProvisionerDaemons :exec
|
||||
-- Delete provisioner daemons that have been created at least a week ago
|
||||
-- and have not connected to coderd since a week.
|
||||
|
Reference in New Issue
Block a user