Skip to content

feat: implement runtime configuration package with multi-org support #14624

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add database queries against site_configs
Signed-off-by: Danny Kopping <danny@coder.com>
  • Loading branch information
dannykopping authored and Emyrk committed Sep 6, 2024
commit f97ca897c681cb8c74a85c163d950c8f569a24a3
15 changes: 15 additions & 0 deletions coderd/database/dbauthz/dbauthz.go
Original file line number Diff line number Diff line change
Expand Up @@ -1183,6 +1183,11 @@ func (q *querier) DeleteReplicasUpdatedBefore(ctx context.Context, updatedAt tim
return q.db.DeleteReplicasUpdatedBefore(ctx, updatedAt)
}

func (q *querier) DeleteRuntimeConfig(ctx context.Context, key string) error {
// TODO: auth
return q.db.DeleteRuntimeConfig(ctx, key)
}

func (q *querier) DeleteTailnetAgent(ctx context.Context, arg database.DeleteTailnetAgentParams) (database.DeleteTailnetAgentRow, error) {
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceTailnetCoordinator); err != nil {
return database.DeleteTailnetAgentRow{}, err
Expand Down Expand Up @@ -1856,6 +1861,11 @@ func (q *querier) GetReplicasUpdatedAfter(ctx context.Context, updatedAt time.Ti
return q.db.GetReplicasUpdatedAfter(ctx, updatedAt)
}

func (q *querier) GetRuntimeConfig(ctx context.Context, key string) (string, error) {
// TODO: auth
return q.db.GetRuntimeConfig(ctx, key)
}

func (q *querier) GetTailnetAgents(ctx context.Context, id uuid.UUID) ([]database.TailnetAgent, error) {
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceTailnetCoordinator); err != nil {
return nil, err
Expand Down Expand Up @@ -3906,6 +3916,11 @@ func (q *querier) UpsertProvisionerDaemon(ctx context.Context, arg database.Upse
return q.db.UpsertProvisionerDaemon(ctx, arg)
}

func (q *querier) UpsertRuntimeConfig(ctx context.Context, arg database.UpsertRuntimeConfigParams) error {
// TODO: auth
return q.db.UpsertRuntimeConfig(ctx, arg)
}

func (q *querier) UpsertTailnetAgent(ctx context.Context, arg database.UpsertTailnetAgentParams) (database.TailnetAgent, error) {
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceTailnetCoordinator); err != nil {
return database.TailnetAgent{}, err
Expand Down
36 changes: 36 additions & 0 deletions coderd/database/dbmem/dbmem.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"golang.org/x/xerrors"

"github.com/coder/coder/v2/coderd/notifications/types"
"github.com/coder/coder/v2/coderd/runtimeconfig"

"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbtime"
Expand Down Expand Up @@ -84,6 +85,7 @@ func New() database.Store {
workspaceProxies: make([]database.WorkspaceProxy, 0),
customRoles: make([]database.CustomRole, 0),
locks: map[int64]struct{}{},
runtimeConfig: map[string]string{},
},
}
// Always start with a default org. Matching migration 198.
Expand Down Expand Up @@ -194,6 +196,7 @@ type data struct {
workspaces []database.Workspace
workspaceProxies []database.WorkspaceProxy
customRoles []database.CustomRole
runtimeConfig map[string]string
// Locks is a map of lock names. Any keys within the map are currently
// locked.
locks map[int64]struct{}
Expand Down Expand Up @@ -1928,6 +1931,14 @@ func (q *FakeQuerier) DeleteReplicasUpdatedBefore(_ context.Context, before time
return nil
}

func (q *FakeQuerier) DeleteRuntimeConfig(_ context.Context, key string) error {
q.mutex.Lock()
defer q.mutex.Unlock()

delete(q.runtimeConfig, key)
return nil
}

func (*FakeQuerier) DeleteTailnetAgent(context.Context, database.DeleteTailnetAgentParams) (database.DeleteTailnetAgentRow, error) {
return database.DeleteTailnetAgentRow{}, ErrUnimplemented
}
Expand Down Expand Up @@ -3505,6 +3516,18 @@ func (q *FakeQuerier) GetReplicasUpdatedAfter(_ context.Context, updatedAt time.
return replicas, nil
}

func (q *FakeQuerier) GetRuntimeConfig(_ context.Context, key string) (string, error) {
q.mutex.Lock()
defer q.mutex.Unlock()

val, ok := q.runtimeConfig[key]
if !ok {
return "", runtimeconfig.EntryNotFound
}

return val, nil
}

func (*FakeQuerier) GetTailnetAgents(context.Context, uuid.UUID) ([]database.TailnetAgent, error) {
return nil, ErrUnimplemented
}
Expand Down Expand Up @@ -9186,6 +9209,19 @@ func (q *FakeQuerier) UpsertProvisionerDaemon(_ context.Context, arg database.Up
return d, nil
}

func (q *FakeQuerier) UpsertRuntimeConfig(ctx context.Context, arg database.UpsertRuntimeConfigParams) error {
err := validateDatabaseType(arg)
if err != nil {
return err
}

q.mutex.Lock()
defer q.mutex.Unlock()

q.runtimeConfig[arg.Key] = arg.Value
return nil
}

func (*FakeQuerier) UpsertTailnetAgent(context.Context, database.UpsertTailnetAgentParams) (database.TailnetAgent, error) {
return database.TailnetAgent{}, ErrUnimplemented
}
Expand Down
21 changes: 21 additions & 0 deletions coderd/database/dbmetrics/dbmetrics.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions coderd/database/querier.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions coderd/database/queries.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions coderd/database/queries/siteconfig.sql
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,14 @@ SELECT
INSERT INTO site_configs (key, value) VALUES ('notifications_settings', $1)
ON CONFLICT (key) DO UPDATE SET value = $1 WHERE site_configs.key = 'notifications_settings';

-- name: GetRuntimeConfig :one
SELECT value FROM site_configs WHERE site_configs.key = $1;

-- name: UpsertRuntimeConfig :exec
INSERT INTO site_configs (key, value) VALUES ($1, $2)
ON CONFLICT (key) DO UPDATE SET value = $2 WHERE site_configs.key = $1;

-- name: DeleteRuntimeConfig :exec
DELETE FROM site_configs
WHERE site_configs.key = $1;

5 changes: 3 additions & 2 deletions coderd/runtimeconfig/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/stretchr/testify/require"

"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/runtimeconfig"
"github.com/coder/coder/v2/coderd/util/ptr"
"github.com/coder/coder/v2/codersdk"
Expand Down Expand Up @@ -69,7 +70,7 @@ func TestConfig(t *testing.T) {
t.Parallel()

ctx := testutil.Context(t, testutil.WaitShort)
store := runtimeconfig.NewInMemoryStore()
store := dbmem.New()
resolver := runtimeconfig.NewOrgResolver(altOrg.ID, runtimeconfig.NewStoreResolver(store))
mutator := runtimeconfig.NewOrgMutator(altOrg.ID, runtimeconfig.NewStoreMutator(store))

Expand Down Expand Up @@ -102,7 +103,7 @@ func TestConfig(t *testing.T) {
t.Parallel()

ctx := testutil.Context(t, testutil.WaitShort)
store := runtimeconfig.NewInMemoryStore()
store := dbmem.New()
resolver := runtimeconfig.NewOrgResolver(altOrg.ID, runtimeconfig.NewStoreResolver(store))
mutator := runtimeconfig.NewOrgMutator(altOrg.ID, runtimeconfig.NewStoreMutator(store))

Expand Down
4 changes: 3 additions & 1 deletion coderd/runtimeconfig/mutator.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (

"github.com/google/uuid"
"golang.org/x/xerrors"

"github.com/coder/coder/v2/coderd/database"
)

type StoreMutator struct {
Expand All @@ -19,7 +21,7 @@ func NewStoreMutator(store Store) *StoreMutator {
}

func (s *StoreMutator) MutateByKey(ctx context.Context, key, val string) error {
err := s.store.UpsertRuntimeSetting(ctx, key, val)
err := s.store.UpsertRuntimeConfig(ctx, database.UpsertRuntimeConfigParams{Key: key, Value: val})
if err != nil {
return xerrors.Errorf("update %q: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion coderd/runtimeconfig/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func (s StoreResolver) ResolveByKey(ctx context.Context, key string) (string, er
panic("developer error: store must be set")
}

val, err := s.store.GetRuntimeSetting(ctx, key)
val, err := s.store.GetRuntimeConfig(ctx, key)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return "", xerrors.Errorf("%q: %w", key, EntryNotFound)
Expand Down
46 changes: 5 additions & 41 deletions coderd/runtimeconfig/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,16 @@ package runtimeconfig

import (
"context"
"sync"

"golang.org/x/xerrors"

"github.com/coder/coder/v2/coderd/database"
)

var EntryNotFound = xerrors.New("entry not found")

type Store interface {
GetRuntimeSetting(ctx context.Context, key string) (string, error)
UpsertRuntimeSetting(ctx context.Context, key, value string) error
DeleteRuntimeSetting(ctx context.Context, key string) error
}

type InMemoryStore struct {
mu sync.Mutex
store map[string]string
}

func NewInMemoryStore() *InMemoryStore {
return &InMemoryStore{store: make(map[string]string)}
}

func (s *InMemoryStore) GetRuntimeSetting(_ context.Context, key string) (string, error) {
s.mu.Lock()
defer s.mu.Unlock()

val, ok := s.store[key]
if !ok {
return "", EntryNotFound
}

return val, nil
}

func (s *InMemoryStore) UpsertRuntimeSetting(_ context.Context, key, value string) error {
s.mu.Lock()
defer s.mu.Unlock()

s.store[key] = value
return nil
}

func (s *InMemoryStore) DeleteRuntimeSetting(_ context.Context, key string) error {
s.mu.Lock()
defer s.mu.Unlock()

delete(s.store, key)
return nil
GetRuntimeConfig(ctx context.Context, key string) (string, error)
UpsertRuntimeConfig(ctx context.Context, arg database.UpsertRuntimeConfigParams) error
DeleteRuntimeConfig(ctx context.Context, key string) error
}