chore: add provisioner key crud apis (#13857)

This commit is contained in:
Garrett Delfosse
2024-07-16 13:27:12 -04:00
committed by GitHub
parent a5e4bf38fe
commit b697c6939a
35 changed files with 1447 additions and 16 deletions
+20
View File
@@ -1074,6 +1074,10 @@ func (q *querier) DeleteOrganizationMember(ctx context.Context, arg database.Del
}, q.db.DeleteOrganizationMember)(ctx, arg)
}
func (q *querier) DeleteProvisionerKey(ctx context.Context, id uuid.UUID) error {
return deleteQ(q.log, q.auth, q.db.GetProvisionerKeyByID, q.db.DeleteProvisionerKey)(ctx, id)
}
func (q *querier) DeleteReplicasUpdatedBefore(ctx context.Context, updatedAt time.Time) error {
if err := q.authorizeContext(ctx, policy.ActionDelete, rbac.ResourceSystem); err != nil {
return err
@@ -1671,6 +1675,14 @@ func (q *querier) GetProvisionerJobsCreatedAfter(ctx context.Context, createdAt
return q.db.GetProvisionerJobsCreatedAfter(ctx, createdAt)
}
func (q *querier) GetProvisionerKeyByID(ctx context.Context, id uuid.UUID) (database.ProvisionerKey, error) {
return fetch(q.log, q.auth, q.db.GetProvisionerKeyByID)(ctx, id)
}
func (q *querier) GetProvisionerKeyByName(ctx context.Context, name database.GetProvisionerKeyByNameParams) (database.ProvisionerKey, error) {
return fetch(q.log, q.auth, q.db.GetProvisionerKeyByName)(ctx, name)
}
func (q *querier) GetProvisionerLogsAfterID(ctx context.Context, arg database.GetProvisionerLogsAfterIDParams) ([]database.ProvisionerJobLog, error) {
// Authorized read on job lets the actor also read the logs.
_, err := q.GetProvisionerJobByID(ctx, arg.JobID)
@@ -2615,6 +2627,10 @@ func (q *querier) InsertProvisionerJobLogs(ctx context.Context, arg database.Ins
return q.db.InsertProvisionerJobLogs(ctx, arg)
}
func (q *querier) InsertProvisionerKey(ctx context.Context, arg database.InsertProvisionerKeyParams) (database.ProvisionerKey, error) {
return insert(q.log, q.auth, rbac.ResourceProvisionerKeys.InOrg(arg.OrganizationID).WithID(arg.ID), q.db.InsertProvisionerKey)(ctx, arg)
}
func (q *querier) InsertReplica(ctx context.Context, arg database.InsertReplicaParams) (database.Replica, error) {
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil {
return database.Replica{}, err
@@ -2843,6 +2859,10 @@ func (q *querier) InsertWorkspaceResourceMetadata(ctx context.Context, arg datab
return q.db.InsertWorkspaceResourceMetadata(ctx, arg)
}
func (q *querier) ListProvisionerKeysByOrganization(ctx context.Context, organizationID uuid.UUID) ([]database.ProvisionerKey, error) {
return fetchWithPostFilter(q.auth, policy.ActionRead, q.db.ListProvisionerKeysByOrganization)(ctx, organizationID)
}
func (q *querier) ListWorkspaceAgentPortShares(ctx context.Context, workspaceID uuid.UUID) ([]database.WorkspaceAgentPortShare, error) {
workspace, err := q.db.GetWorkspaceByID(ctx, workspaceID)
if err != nil {
+53
View File
@@ -5,6 +5,7 @@ import (
"database/sql"
"encoding/json"
"reflect"
"strings"
"testing"
"time"
@@ -1800,6 +1801,58 @@ func (s *MethodTestSuite) TestWorkspacePortSharing() {
}))
}
func (s *MethodTestSuite) TestProvisionerKeys() {
s.Run("InsertProvisionerKey", s.Subtest(func(db database.Store, check *expects) {
org := dbgen.Organization(s.T(), db, database.Organization{})
pk := database.ProvisionerKey{
ID: uuid.New(),
CreatedAt: time.Now(),
OrganizationID: org.ID,
Name: strings.ToLower(coderdtest.RandomName(s.T())),
HashedSecret: []byte(coderdtest.RandomName(s.T())),
}
//nolint:gosimple // casting is not a simplification
check.Args(database.InsertProvisionerKeyParams{
ID: pk.ID,
CreatedAt: pk.CreatedAt,
OrganizationID: pk.OrganizationID,
Name: pk.Name,
HashedSecret: pk.HashedSecret,
}).Asserts(pk, policy.ActionCreate).Returns(pk)
}))
s.Run("GetProvisionerKeyByID", s.Subtest(func(db database.Store, check *expects) {
org := dbgen.Organization(s.T(), db, database.Organization{})
pk := dbgen.ProvisionerKey(s.T(), db, database.ProvisionerKey{OrganizationID: org.ID})
check.Args(pk.ID).Asserts(pk, policy.ActionRead).Returns(pk)
}))
s.Run("GetProvisionerKeyByName", s.Subtest(func(db database.Store, check *expects) {
org := dbgen.Organization(s.T(), db, database.Organization{})
pk := dbgen.ProvisionerKey(s.T(), db, database.ProvisionerKey{OrganizationID: org.ID})
check.Args(database.GetProvisionerKeyByNameParams{
OrganizationID: org.ID,
Name: pk.Name,
}).Asserts(pk, policy.ActionRead).Returns(pk)
}))
s.Run("ListProvisionerKeysByOrganization", s.Subtest(func(db database.Store, check *expects) {
org := dbgen.Organization(s.T(), db, database.Organization{})
pk := dbgen.ProvisionerKey(s.T(), db, database.ProvisionerKey{OrganizationID: org.ID})
pks := []database.ProvisionerKey{
{
ID: pk.ID,
CreatedAt: pk.CreatedAt,
OrganizationID: pk.OrganizationID,
Name: pk.Name,
},
}
check.Args(org.ID).Asserts(pk, policy.ActionRead).Returns(pks)
}))
s.Run("DeleteProvisionerKey", s.Subtest(func(db database.Store, check *expects) {
org := dbgen.Organization(s.T(), db, database.Organization{})
pk := dbgen.ProvisionerKey(s.T(), db, database.ProvisionerKey{OrganizationID: org.ID})
check.Args(pk.ID).Asserts(pk, policy.ActionDelete).Returns()
}))
}
func (s *MethodTestSuite) TestExtraMethods() {
s.Run("GetProvisionerDaemons", s.Subtest(func(db database.Store, check *expects) {
d, err := db.UpsertProvisionerDaemon(context.Background(), database.UpsertProvisionerDaemonParams{
+12
View File
@@ -465,6 +465,18 @@ func ProvisionerJob(t testing.TB, db database.Store, ps pubsub.Pubsub, orig data
return job
}
func ProvisionerKey(t testing.TB, db database.Store, orig database.ProvisionerKey) database.ProvisionerKey {
key, err := db.InsertProvisionerKey(genCtx, database.InsertProvisionerKeyParams{
ID: takeFirst(orig.ID, uuid.New()),
CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
OrganizationID: takeFirst(orig.OrganizationID, uuid.New()),
Name: takeFirst(orig.Name, namesgenerator.GetRandomName(1)),
HashedSecret: orig.HashedSecret,
})
require.NoError(t, err, "insert provisioner key")
return key
}
func WorkspaceApp(t testing.TB, db database.Store, orig database.WorkspaceApp) database.WorkspaceApp {
resource, err := db.InsertWorkspaceApp(genCtx, database.InsertWorkspaceAppParams{
ID: takeFirst(orig.ID, uuid.New()),
+96
View File
@@ -168,6 +168,7 @@ type data struct {
provisionerDaemons []database.ProvisionerDaemon
provisionerJobLogs []database.ProvisionerJobLog
provisionerJobs []database.ProvisionerJob
provisionerKeys []database.ProvisionerKey
replicas []database.Replica
templateVersions []database.TemplateVersionTable
templateVersionParameters []database.TemplateVersionParameter
@@ -268,6 +269,13 @@ func validateDatabaseType(args interface{}) error {
return nil
}
func newUniqueConstraintError(uc database.UniqueConstraint) *pq.Error {
newErr := *errUniqueConstraint
newErr.Constraint = string(uc)
return &newErr
}
func (*FakeQuerier) Ping(_ context.Context) (time.Duration, error) {
return 0, nil
}
@@ -1734,6 +1742,20 @@ func (q *FakeQuerier) DeleteOrganizationMember(_ context.Context, arg database.D
return nil
}
func (q *FakeQuerier) DeleteProvisionerKey(_ context.Context, id uuid.UUID) error {
q.mutex.Lock()
defer q.mutex.Unlock()
for i, key := range q.provisionerKeys {
if key.ID == id {
q.provisionerKeys = append(q.provisionerKeys[:i], q.provisionerKeys[i+1:]...)
return nil
}
}
return sql.ErrNoRows
}
func (q *FakeQuerier) DeleteReplicasUpdatedBefore(_ context.Context, before time.Time) error {
q.mutex.Lock()
defer q.mutex.Unlock()
@@ -3195,6 +3217,32 @@ func (q *FakeQuerier) GetProvisionerJobsCreatedAfter(_ context.Context, after ti
return jobs, nil
}
func (q *FakeQuerier) GetProvisionerKeyByID(_ context.Context, id uuid.UUID) (database.ProvisionerKey, error) {
q.mutex.RLock()
defer q.mutex.RUnlock()
for _, key := range q.provisionerKeys {
if key.ID == id {
return key, nil
}
}
return database.ProvisionerKey{}, sql.ErrNoRows
}
func (q *FakeQuerier) GetProvisionerKeyByName(_ context.Context, arg database.GetProvisionerKeyByNameParams) (database.ProvisionerKey, error) {
q.mutex.RLock()
defer q.mutex.RUnlock()
for _, key := range q.provisionerKeys {
if strings.EqualFold(key.Name, arg.Name) && key.OrganizationID == arg.OrganizationID {
return key, nil
}
}
return database.ProvisionerKey{}, sql.ErrNoRows
}
func (q *FakeQuerier) GetProvisionerLogsAfterID(_ context.Context, arg database.GetProvisionerLogsAfterIDParams) ([]database.ProvisionerJobLog, error) {
if err := validateDatabaseType(arg); err != nil {
return nil, err
@@ -6493,6 +6541,34 @@ func (q *FakeQuerier) InsertProvisionerJobLogs(_ context.Context, arg database.I
return logs, nil
}
func (q *FakeQuerier) InsertProvisionerKey(_ context.Context, arg database.InsertProvisionerKeyParams) (database.ProvisionerKey, error) {
err := validateDatabaseType(arg)
if err != nil {
return database.ProvisionerKey{}, err
}
q.mutex.Lock()
defer q.mutex.Unlock()
for _, key := range q.provisionerKeys {
if key.ID == arg.ID || (key.OrganizationID == arg.OrganizationID && strings.EqualFold(key.Name, arg.Name)) {
return database.ProvisionerKey{}, newUniqueConstraintError(database.UniqueProvisionerKeysOrganizationIDNameIndex)
}
}
//nolint:gosimple
provisionerKey := database.ProvisionerKey{
ID: arg.ID,
CreatedAt: arg.CreatedAt,
OrganizationID: arg.OrganizationID,
Name: strings.ToLower(arg.Name),
HashedSecret: arg.HashedSecret,
}
q.provisionerKeys = append(q.provisionerKeys, provisionerKey)
return provisionerKey, nil
}
func (q *FakeQuerier) InsertReplica(_ context.Context, arg database.InsertReplicaParams) (database.Replica, error) {
if err := validateDatabaseType(arg); err != nil {
return database.Replica{}, err
@@ -7170,6 +7246,26 @@ func (q *FakeQuerier) InsertWorkspaceResourceMetadata(_ context.Context, arg dat
return metadata, nil
}
func (q *FakeQuerier) ListProvisionerKeysByOrganization(_ context.Context, organizationID uuid.UUID) ([]database.ProvisionerKey, error) {
q.mutex.RLock()
defer q.mutex.RUnlock()
keys := make([]database.ProvisionerKey, 0)
for _, key := range q.provisionerKeys {
if key.OrganizationID == organizationID {
keys = append(keys, database.ProvisionerKey{
ID: key.ID,
CreatedAt: key.CreatedAt,
OrganizationID: key.OrganizationID,
Name: key.Name,
HashedSecret: key.HashedSecret,
})
}
}
return keys, nil
}
func (q *FakeQuerier) ListWorkspaceAgentPortShares(_ context.Context, workspaceID uuid.UUID) ([]database.WorkspaceAgentPortShare, error) {
q.mutex.Lock()
defer q.mutex.Unlock()
+35
View File
@@ -326,6 +326,13 @@ func (m metricsStore) DeleteOrganizationMember(ctx context.Context, arg database
return r0
}
func (m metricsStore) DeleteProvisionerKey(ctx context.Context, id uuid.UUID) error {
start := time.Now()
r0 := m.s.DeleteProvisionerKey(ctx, id)
m.queryLatencies.WithLabelValues("DeleteProvisionerKey").Observe(time.Since(start).Seconds())
return r0
}
func (m metricsStore) DeleteReplicasUpdatedBefore(ctx context.Context, updatedAt time.Time) error {
start := time.Now()
err := m.s.DeleteReplicasUpdatedBefore(ctx, updatedAt)
@@ -900,6 +907,20 @@ func (m metricsStore) GetProvisionerJobsCreatedAfter(ctx context.Context, create
return jobs, err
}
func (m metricsStore) GetProvisionerKeyByID(ctx context.Context, id uuid.UUID) (database.ProvisionerKey, error) {
start := time.Now()
r0, r1 := m.s.GetProvisionerKeyByID(ctx, id)
m.queryLatencies.WithLabelValues("GetProvisionerKeyByID").Observe(time.Since(start).Seconds())
return r0, r1
}
func (m metricsStore) GetProvisionerKeyByName(ctx context.Context, name database.GetProvisionerKeyByNameParams) (database.ProvisionerKey, error) {
start := time.Now()
r0, r1 := m.s.GetProvisionerKeyByName(ctx, name)
m.queryLatencies.WithLabelValues("GetProvisionerKeyByName").Observe(time.Since(start).Seconds())
return r0, r1
}
func (m metricsStore) GetProvisionerLogsAfterID(ctx context.Context, arg database.GetProvisionerLogsAfterIDParams) ([]database.ProvisionerJobLog, error) {
start := time.Now()
logs, err := m.s.GetProvisionerLogsAfterID(ctx, arg)
@@ -1642,6 +1663,13 @@ func (m metricsStore) InsertProvisionerJobLogs(ctx context.Context, arg database
return logs, err
}
func (m metricsStore) InsertProvisionerKey(ctx context.Context, arg database.InsertProvisionerKeyParams) (database.ProvisionerKey, error) {
start := time.Now()
r0, r1 := m.s.InsertProvisionerKey(ctx, arg)
m.queryLatencies.WithLabelValues("InsertProvisionerKey").Observe(time.Since(start).Seconds())
return r0, r1
}
func (m metricsStore) InsertReplica(ctx context.Context, arg database.InsertReplicaParams) (database.Replica, error) {
start := time.Now()
replica, err := m.s.InsertReplica(ctx, arg)
@@ -1803,6 +1831,13 @@ func (m metricsStore) InsertWorkspaceResourceMetadata(ctx context.Context, arg d
return metadata, err
}
func (m metricsStore) ListProvisionerKeysByOrganization(ctx context.Context, organizationID uuid.UUID) ([]database.ProvisionerKey, error) {
start := time.Now()
r0, r1 := m.s.ListProvisionerKeysByOrganization(ctx, organizationID)
m.queryLatencies.WithLabelValues("ListProvisionerKeysByOrganization").Observe(time.Since(start).Seconds())
return r0, r1
}
func (m metricsStore) ListWorkspaceAgentPortShares(ctx context.Context, workspaceID uuid.UUID) ([]database.WorkspaceAgentPortShare, error) {
start := time.Now()
r0, r1 := m.s.ListWorkspaceAgentPortShares(ctx, workspaceID)
+74
View File
@@ -542,6 +542,20 @@ func (mr *MockStoreMockRecorder) DeleteOrganizationMember(arg0, arg1 any) *gomoc
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteOrganizationMember", reflect.TypeOf((*MockStore)(nil).DeleteOrganizationMember), arg0, arg1)
}
// DeleteProvisionerKey mocks base method.
func (m *MockStore) DeleteProvisionerKey(arg0 context.Context, arg1 uuid.UUID) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteProvisionerKey", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// DeleteProvisionerKey indicates an expected call of DeleteProvisionerKey.
func (mr *MockStoreMockRecorder) DeleteProvisionerKey(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteProvisionerKey", reflect.TypeOf((*MockStore)(nil).DeleteProvisionerKey), arg0, arg1)
}
// DeleteReplicasUpdatedBefore mocks base method.
func (m *MockStore) DeleteReplicasUpdatedBefore(arg0 context.Context, arg1 time.Time) error {
m.ctrl.T.Helper()
@@ -1811,6 +1825,36 @@ func (mr *MockStoreMockRecorder) GetProvisionerJobsCreatedAfter(arg0, arg1 any)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProvisionerJobsCreatedAfter", reflect.TypeOf((*MockStore)(nil).GetProvisionerJobsCreatedAfter), arg0, arg1)
}
// GetProvisionerKeyByID mocks base method.
func (m *MockStore) GetProvisionerKeyByID(arg0 context.Context, arg1 uuid.UUID) (database.ProvisionerKey, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetProvisionerKeyByID", arg0, arg1)
ret0, _ := ret[0].(database.ProvisionerKey)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetProvisionerKeyByID indicates an expected call of GetProvisionerKeyByID.
func (mr *MockStoreMockRecorder) GetProvisionerKeyByID(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProvisionerKeyByID", reflect.TypeOf((*MockStore)(nil).GetProvisionerKeyByID), arg0, arg1)
}
// GetProvisionerKeyByName mocks base method.
func (m *MockStore) GetProvisionerKeyByName(arg0 context.Context, arg1 database.GetProvisionerKeyByNameParams) (database.ProvisionerKey, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetProvisionerKeyByName", arg0, arg1)
ret0, _ := ret[0].(database.ProvisionerKey)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetProvisionerKeyByName indicates an expected call of GetProvisionerKeyByName.
func (mr *MockStoreMockRecorder) GetProvisionerKeyByName(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProvisionerKeyByName", reflect.TypeOf((*MockStore)(nil).GetProvisionerKeyByName), arg0, arg1)
}
// GetProvisionerLogsAfterID mocks base method.
func (m *MockStore) GetProvisionerLogsAfterID(arg0 context.Context, arg1 database.GetProvisionerLogsAfterIDParams) ([]database.ProvisionerJobLog, error) {
m.ctrl.T.Helper()
@@ -3441,6 +3485,21 @@ func (mr *MockStoreMockRecorder) InsertProvisionerJobLogs(arg0, arg1 any) *gomoc
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertProvisionerJobLogs", reflect.TypeOf((*MockStore)(nil).InsertProvisionerJobLogs), arg0, arg1)
}
// InsertProvisionerKey mocks base method.
func (m *MockStore) InsertProvisionerKey(arg0 context.Context, arg1 database.InsertProvisionerKeyParams) (database.ProvisionerKey, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "InsertProvisionerKey", arg0, arg1)
ret0, _ := ret[0].(database.ProvisionerKey)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// InsertProvisionerKey indicates an expected call of InsertProvisionerKey.
func (mr *MockStoreMockRecorder) InsertProvisionerKey(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertProvisionerKey", reflect.TypeOf((*MockStore)(nil).InsertProvisionerKey), arg0, arg1)
}
// InsertReplica mocks base method.
func (m *MockStore) InsertReplica(arg0 context.Context, arg1 database.InsertReplicaParams) (database.Replica, error) {
m.ctrl.T.Helper()
@@ -3778,6 +3837,21 @@ func (mr *MockStoreMockRecorder) InsertWorkspaceResourceMetadata(arg0, arg1 any)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertWorkspaceResourceMetadata", reflect.TypeOf((*MockStore)(nil).InsertWorkspaceResourceMetadata), arg0, arg1)
}
// ListProvisionerKeysByOrganization mocks base method.
func (m *MockStore) ListProvisionerKeysByOrganization(arg0 context.Context, arg1 uuid.UUID) ([]database.ProvisionerKey, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListProvisionerKeysByOrganization", arg0, arg1)
ret0, _ := ret[0].([]database.ProvisionerKey)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ListProvisionerKeysByOrganization indicates an expected call of ListProvisionerKeysByOrganization.
func (mr *MockStoreMockRecorder) ListProvisionerKeysByOrganization(arg0, arg1 any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListProvisionerKeysByOrganization", reflect.TypeOf((*MockStore)(nil).ListProvisionerKeysByOrganization), arg0, arg1)
}
// ListWorkspaceAgentPortShares mocks base method.
func (m *MockStore) ListWorkspaceAgentPortShares(arg0 context.Context, arg1 uuid.UUID) ([]database.WorkspaceAgentPortShare, error) {
m.ctrl.T.Helper()
+16
View File
@@ -749,6 +749,14 @@ END) STORED NOT NULL
COMMENT ON COLUMN provisioner_jobs.job_status IS 'Computed column to track the status of the job.';
CREATE TABLE provisioner_keys (
id uuid NOT NULL,
created_at timestamp with time zone NOT NULL,
organization_id uuid NOT NULL,
name character varying(64) NOT NULL,
hashed_secret bytea NOT NULL
);
CREATE TABLE replicas (
id uuid NOT NULL,
created_at timestamp with time zone NOT NULL,
@@ -1584,6 +1592,9 @@ ALTER TABLE ONLY provisioner_job_logs
ALTER TABLE ONLY provisioner_jobs
ADD CONSTRAINT provisioner_jobs_pkey PRIMARY KEY (id);
ALTER TABLE ONLY provisioner_keys
ADD CONSTRAINT provisioner_keys_pkey PRIMARY KEY (id);
ALTER TABLE ONLY site_configs
ADD CONSTRAINT site_configs_key_key UNIQUE (key);
@@ -1743,6 +1754,8 @@ CREATE INDEX provisioner_job_logs_id_job_id_idx ON provisioner_job_logs USING bt
CREATE INDEX provisioner_jobs_started_at_idx ON provisioner_jobs USING btree (started_at) WHERE (started_at IS NULL);
CREATE UNIQUE INDEX provisioner_keys_organization_id_name_idx ON provisioner_keys USING btree (organization_id, lower((name)::text));
CREATE INDEX template_usage_stats_start_time_idx ON template_usage_stats USING btree (start_time DESC);
COMMENT ON INDEX template_usage_stats_start_time_idx IS 'Index for querying MAX(start_time).';
@@ -1867,6 +1880,9 @@ ALTER TABLE ONLY provisioner_job_logs
ALTER TABLE ONLY provisioner_jobs
ADD CONSTRAINT provisioner_jobs_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
ALTER TABLE ONLY provisioner_keys
ADD CONSTRAINT provisioner_keys_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
ALTER TABLE ONLY tailnet_agents
ADD CONSTRAINT tailnet_agents_coordinator_id_fkey FOREIGN KEY (coordinator_id) REFERENCES tailnet_coordinators(id) ON DELETE CASCADE;
@@ -28,6 +28,7 @@ const (
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;
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;
@@ -0,0 +1 @@
DROP TABLE provisioner_keys;
@@ -0,0 +1,9 @@
CREATE TABLE provisioner_keys (
id uuid PRIMARY KEY,
created_at timestamptz NOT NULL,
organization_id uuid NOT NULL REFERENCES organizations (id) ON DELETE CASCADE,
name varchar(64) NOT NULL,
hashed_secret bytea NOT NULL
);
CREATE UNIQUE INDEX provisioner_keys_organization_id_name_idx ON provisioner_keys USING btree (organization_id, lower(name));
@@ -0,0 +1,4 @@
INSERT INTO provisioner_keys
(id, created_at, organization_id, name, hashed_secret)
VALUES
('b90547be-8870-4d68-8184-e8b2242b7c01', '2021-06-01 00:00:00', 'bb640d07-ca8a-4869-b6bc-ae61ebb2fda1', 'qua', '\xDEADBEEF'::bytea);
+6
View File
@@ -212,6 +212,12 @@ func (p ProvisionerDaemon) RBACObject() rbac.Object {
return rbac.ResourceProvisionerDaemon.WithID(p.ID)
}
func (p ProvisionerKey) RBACObject() rbac.Object {
return rbac.ResourceProvisionerKeys.
WithID(p.ID).
InOrg(p.OrganizationID)
}
func (w WorkspaceProxy) RBACObject() rbac.Object {
return rbac.ResourceWorkspaceProxy.
WithID(w.ID)
+8
View File
@@ -2185,6 +2185,14 @@ type ProvisionerJobLog struct {
ID int64 `db:"id" json:"id"`
}
type ProvisionerKey struct {
ID uuid.UUID `db:"id" json:"id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
Name string `db:"name" json:"name"`
HashedSecret []byte `db:"hashed_secret" json:"hashed_secret"`
}
type Replica struct {
ID uuid.UUID `db:"id" json:"id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
+5
View File
@@ -92,6 +92,7 @@ type sqlcQuerier interface {
DeleteOldWorkspaceAgentStats(ctx context.Context) error
DeleteOrganization(ctx context.Context, id uuid.UUID) error
DeleteOrganizationMember(ctx context.Context, arg DeleteOrganizationMemberParams) error
DeleteProvisionerKey(ctx context.Context, id uuid.UUID) error
DeleteReplicasUpdatedBefore(ctx context.Context, updatedAt time.Time) error
DeleteTailnetAgent(ctx context.Context, arg DeleteTailnetAgentParams) (DeleteTailnetAgentRow, error)
DeleteTailnetClient(ctx context.Context, arg DeleteTailnetClientParams) (DeleteTailnetClientRow, error)
@@ -184,6 +185,8 @@ type sqlcQuerier interface {
GetProvisionerJobsByIDs(ctx context.Context, ids []uuid.UUID) ([]ProvisionerJob, error)
GetProvisionerJobsByIDsWithQueuePosition(ctx context.Context, ids []uuid.UUID) ([]GetProvisionerJobsByIDsWithQueuePositionRow, error)
GetProvisionerJobsCreatedAfter(ctx context.Context, createdAt time.Time) ([]ProvisionerJob, error)
GetProvisionerKeyByID(ctx context.Context, id uuid.UUID) (ProvisionerKey, error)
GetProvisionerKeyByName(ctx context.Context, arg GetProvisionerKeyByNameParams) (ProvisionerKey, error)
GetProvisionerLogsAfterID(ctx context.Context, arg GetProvisionerLogsAfterIDParams) ([]ProvisionerJobLog, error)
GetQuotaAllowanceForUser(ctx context.Context, userID uuid.UUID) (int64, error)
GetQuotaConsumedForUser(ctx context.Context, ownerID uuid.UUID) (int64, error)
@@ -346,6 +349,7 @@ type sqlcQuerier interface {
InsertOrganizationMember(ctx context.Context, arg InsertOrganizationMemberParams) (OrganizationMember, error)
InsertProvisionerJob(ctx context.Context, arg InsertProvisionerJobParams) (ProvisionerJob, error)
InsertProvisionerJobLogs(ctx context.Context, arg InsertProvisionerJobLogsParams) ([]ProvisionerJobLog, error)
InsertProvisionerKey(ctx context.Context, arg InsertProvisionerKeyParams) (ProvisionerKey, error)
InsertReplica(ctx context.Context, arg InsertReplicaParams) (Replica, error)
InsertTemplate(ctx context.Context, arg InsertTemplateParams) error
InsertTemplateVersion(ctx context.Context, arg InsertTemplateVersionParams) error
@@ -370,6 +374,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)
ListProvisionerKeysByOrganization(ctx context.Context, organizationID uuid.UUID) ([]ProvisionerKey, error)
ListWorkspaceAgentPortShares(ctx context.Context, workspaceID uuid.UUID) ([]WorkspaceAgentPortShare, error)
// Arguments are optional with uuid.Nil to ignore.
// - Use just 'organization_id' to get all members of an org
+141
View File
@@ -5455,6 +5455,147 @@ func (q *sqlQuerier) UpdateProvisionerJobWithCompleteByID(ctx context.Context, a
return err
}
const deleteProvisionerKey = `-- name: DeleteProvisionerKey :exec
DELETE FROM
provisioner_keys
WHERE
id = $1
`
func (q *sqlQuerier) DeleteProvisionerKey(ctx context.Context, id uuid.UUID) error {
_, err := q.db.ExecContext(ctx, deleteProvisionerKey, id)
return err
}
const getProvisionerKeyByID = `-- name: GetProvisionerKeyByID :one
SELECT
id, created_at, organization_id, name, hashed_secret
FROM
provisioner_keys
WHERE
id = $1
`
func (q *sqlQuerier) GetProvisionerKeyByID(ctx context.Context, id uuid.UUID) (ProvisionerKey, error) {
row := q.db.QueryRowContext(ctx, getProvisionerKeyByID, id)
var i ProvisionerKey
err := row.Scan(
&i.ID,
&i.CreatedAt,
&i.OrganizationID,
&i.Name,
&i.HashedSecret,
)
return i, err
}
const getProvisionerKeyByName = `-- name: GetProvisionerKeyByName :one
SELECT
id, created_at, organization_id, name, hashed_secret
FROM
provisioner_keys
WHERE
organization_id = $1
AND
lower(name) = lower($2)
`
type GetProvisionerKeyByNameParams struct {
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
Name string `db:"name" json:"name"`
}
func (q *sqlQuerier) GetProvisionerKeyByName(ctx context.Context, arg GetProvisionerKeyByNameParams) (ProvisionerKey, error) {
row := q.db.QueryRowContext(ctx, getProvisionerKeyByName, arg.OrganizationID, arg.Name)
var i ProvisionerKey
err := row.Scan(
&i.ID,
&i.CreatedAt,
&i.OrganizationID,
&i.Name,
&i.HashedSecret,
)
return i, err
}
const insertProvisionerKey = `-- name: InsertProvisionerKey :one
INSERT INTO
provisioner_keys (
id,
created_at,
organization_id,
name,
hashed_secret
)
VALUES
($1, $2, $3, lower($5), $4) RETURNING id, created_at, organization_id, name, hashed_secret
`
type InsertProvisionerKeyParams struct {
ID uuid.UUID `db:"id" json:"id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
HashedSecret []byte `db:"hashed_secret" json:"hashed_secret"`
Name string `db:"name" json:"name"`
}
func (q *sqlQuerier) InsertProvisionerKey(ctx context.Context, arg InsertProvisionerKeyParams) (ProvisionerKey, error) {
row := q.db.QueryRowContext(ctx, insertProvisionerKey,
arg.ID,
arg.CreatedAt,
arg.OrganizationID,
arg.HashedSecret,
arg.Name,
)
var i ProvisionerKey
err := row.Scan(
&i.ID,
&i.CreatedAt,
&i.OrganizationID,
&i.Name,
&i.HashedSecret,
)
return i, err
}
const listProvisionerKeysByOrganization = `-- name: ListProvisionerKeysByOrganization :many
SELECT
id, created_at, organization_id, name, hashed_secret
FROM
provisioner_keys
WHERE
organization_id = $1
`
func (q *sqlQuerier) ListProvisionerKeysByOrganization(ctx context.Context, organizationID uuid.UUID) ([]ProvisionerKey, error) {
rows, err := q.db.QueryContext(ctx, listProvisionerKeysByOrganization, organizationID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ProvisionerKey
for rows.Next() {
var i ProvisionerKey
if err := rows.Scan(
&i.ID,
&i.CreatedAt,
&i.OrganizationID,
&i.Name,
&i.HashedSecret,
); 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 getWorkspaceProxies = `-- name: GetWorkspaceProxies :many
SELECT
id, name, display_name, icon, url, wildcard_hostname, created_at, updated_at, deleted, token_hashed_secret, region_id, derp_enabled, derp_only, version
@@ -0,0 +1,43 @@
-- name: InsertProvisionerKey :one
INSERT INTO
provisioner_keys (
id,
created_at,
organization_id,
name,
hashed_secret
)
VALUES
($1, $2, $3, lower(@name), $4) RETURNING *;
-- name: GetProvisionerKeyByID :one
SELECT
*
FROM
provisioner_keys
WHERE
id = $1;
-- name: GetProvisionerKeyByName :one
SELECT
*
FROM
provisioner_keys
WHERE
organization_id = $1
AND
lower(name) = lower(@name);
-- name: ListProvisionerKeysByOrganization :many
SELECT
*
FROM
provisioner_keys
WHERE
organization_id = $1;
-- name: DeleteProvisionerKey :exec
DELETE FROM
provisioner_keys
WHERE
id = $1;
+2
View File
@@ -44,6 +44,7 @@ const (
UniqueProvisionerDaemonsPkey UniqueConstraint = "provisioner_daemons_pkey" // ALTER TABLE ONLY provisioner_daemons ADD CONSTRAINT provisioner_daemons_pkey PRIMARY KEY (id);
UniqueProvisionerJobLogsPkey UniqueConstraint = "provisioner_job_logs_pkey" // ALTER TABLE ONLY provisioner_job_logs ADD CONSTRAINT provisioner_job_logs_pkey PRIMARY KEY (id);
UniqueProvisionerJobsPkey UniqueConstraint = "provisioner_jobs_pkey" // ALTER TABLE ONLY provisioner_jobs ADD CONSTRAINT provisioner_jobs_pkey PRIMARY KEY (id);
UniqueProvisionerKeysPkey UniqueConstraint = "provisioner_keys_pkey" // ALTER TABLE ONLY provisioner_keys ADD CONSTRAINT provisioner_keys_pkey PRIMARY KEY (id);
UniqueSiteConfigsKeyKey UniqueConstraint = "site_configs_key_key" // ALTER TABLE ONLY site_configs ADD CONSTRAINT site_configs_key_key UNIQUE (key);
UniqueTailnetAgentsPkey UniqueConstraint = "tailnet_agents_pkey" // ALTER TABLE ONLY tailnet_agents ADD CONSTRAINT tailnet_agents_pkey PRIMARY KEY (id, coordinator_id);
UniqueTailnetClientSubscriptionsPkey UniqueConstraint = "tailnet_client_subscriptions_pkey" // ALTER TABLE ONLY tailnet_client_subscriptions ADD CONSTRAINT tailnet_client_subscriptions_pkey PRIMARY KEY (client_id, coordinator_id, agent_id);
@@ -87,6 +88,7 @@ const (
UniqueIndexUsersEmail UniqueConstraint = "idx_users_email" // CREATE UNIQUE INDEX idx_users_email ON users USING btree (email) WHERE (deleted = false);
UniqueIndexUsersUsername UniqueConstraint = "idx_users_username" // CREATE UNIQUE INDEX idx_users_username ON users USING btree (username) WHERE (deleted = false);
UniqueOrganizationsSingleDefaultOrg UniqueConstraint = "organizations_single_default_org" // CREATE UNIQUE INDEX organizations_single_default_org ON organizations USING btree (is_default) WHERE (is_default = true);
UniqueProvisionerKeysOrganizationIDNameIndex UniqueConstraint = "provisioner_keys_organization_id_name_idx" // CREATE UNIQUE INDEX provisioner_keys_organization_id_name_idx ON provisioner_keys USING btree (organization_id, lower((name)::text));
UniqueTemplateUsageStatsStartTimeTemplateIDUserIDIndex UniqueConstraint = "template_usage_stats_start_time_template_id_user_id_idx" // CREATE UNIQUE INDEX template_usage_stats_start_time_template_id_user_id_idx ON template_usage_stats USING btree (start_time, template_id, user_id);
UniqueTemplatesOrganizationIDNameIndex UniqueConstraint = "templates_organization_id_name_idx" // CREATE UNIQUE INDEX templates_organization_id_name_idx ON templates USING btree (organization_id, lower((name)::text)) WHERE (deleted = false);
UniqueUserLinksLinkedIDLoginTypeIndex UniqueConstraint = "user_links_linked_id_login_type_idx" // CREATE UNIQUE INDEX user_links_linked_id_login_type_idx ON user_links USING btree (linked_id, login_type) WHERE (linked_id <> ''::text);