Skip to content

Commit 029f17c

Browse files
committed
Separate DB interface and implementation for rules configs
1 parent c989ef2 commit 029f17c

File tree

6 files changed

+194
-2
lines changed

6 files changed

+194
-2
lines changed

pkg/configs/configs.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ type ID int
77
// A Config is a Cortex configuration for a single user.
88
type Config struct {
99
// RulesFiles maps from a rules filename to file contents.
10-
RulesFiles map[string]string `json:"rules_files"`
11-
AlertmanagerConfig string `json:"alertmanager_config"`
10+
RulesFiles RulesConfig `json:"rules_files"`
11+
AlertmanagerConfig string `json:"alertmanager_config"`
1212
}
1313

1414
// View is what's returned from the Weave Cloud configs service
@@ -21,3 +21,21 @@ type View struct {
2121
ID ID `json:"id"`
2222
Config Config `json:"config"`
2323
}
24+
25+
// GetVersionedRulesConfig specializes the view to just the rules config.
26+
func (v View) GetVersionedRulesConfig() VersionedRulesConfig {
27+
return VersionedRulesConfig{
28+
ID: v.ID,
29+
Config: v.Config.RulesFiles,
30+
}
31+
}
32+
33+
// RulesConfig are the set of rules files for a particular organization.
34+
type RulesConfig map[string]string
35+
36+
// VersionedRulesConfig is a RulesConfig together with a version.
37+
// `data Versioned a = Versioned { id :: ID , config :: a }`
38+
type VersionedRulesConfig struct {
39+
ID ID `json:"id"`
40+
Config RulesConfig `json:"config"`
41+
}

pkg/configs/db/db.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,24 @@ func (cfg *Config) RegisterFlags(f *flag.FlagSet) {
2222
flag.StringVar(&cfg.MigrationsDir, "database.migrations", "", "Path where the database migration files can be found")
2323
}
2424

25+
// RulesDB has ruler-specific DB interfaces.
26+
type RulesDB interface {
27+
// GetRulesConfig gets the user's ruler config
28+
GetRulesConfig(userID string) (configs.VersionedRulesConfig, error)
29+
SetRulesConfig(userID string, config configs.RulesConfig) error
30+
// SetRulesConfig sets the user's ruler config
31+
32+
// GetAllRulesConfigs gets all of the ruler configs
33+
GetAllRulesConfigs() (map[string]configs.VersionedRulesConfig, error)
34+
// GetRulesConfigs gets all of the configs that have been added or have
35+
// changed since the provided config.
36+
GetRulesConfigs(since configs.ID) (map[string]configs.VersionedRulesConfig, error)
37+
}
38+
2539
// DB is the interface for the database.
2640
type DB interface {
41+
RulesDB
42+
2743
GetConfig(userID string) (configs.View, error)
2844
SetConfig(userID string, cfg configs.Config) error
2945

pkg/configs/db/memory/memory.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,46 @@ func (d *DB) GetConfigs(since configs.ID) (map[string]configs.View, error) {
5656
func (d *DB) Close() error {
5757
return nil
5858
}
59+
60+
// GetRulesConfig gets the rules config for a user.
61+
func (d *DB) GetRulesConfig(userID string) (configs.VersionedRulesConfig, error) {
62+
c, ok := d.cfgs[userID]
63+
if !ok {
64+
return configs.VersionedRulesConfig{}, sql.ErrNoRows
65+
}
66+
return c.GetVersionedRulesConfig(), nil
67+
}
68+
69+
// SetRulesConfig sets the rules config for a user.
70+
func (d *DB) SetRulesConfig(userID string, config configs.RulesConfig) error {
71+
c, ok := d.cfgs[userID]
72+
if !ok {
73+
return d.SetConfig(userID, configs.Config{RulesFiles: config})
74+
}
75+
return d.SetConfig(userID, configs.Config{
76+
AlertmanagerConfig: c.Config.AlertmanagerConfig,
77+
RulesFiles: config,
78+
})
79+
}
80+
81+
// GetAllRulesConfigs gets the rules configs for all users that have them.
82+
func (d *DB) GetAllRulesConfigs() (map[string]configs.VersionedRulesConfig, error) {
83+
cfgs := map[string]configs.VersionedRulesConfig{}
84+
for user, c := range d.cfgs {
85+
cfgs[user] = c.GetVersionedRulesConfig()
86+
}
87+
return cfgs, nil
88+
}
89+
90+
// GetRulesConfigs gets the rules configs that have changed
91+
// since the given config version.
92+
func (d *DB) GetRulesConfigs(since configs.ID) (map[string]configs.VersionedRulesConfig, error) {
93+
cfgs := map[string]configs.VersionedRulesConfig{}
94+
for user, c := range d.cfgs {
95+
if c.ID <= since {
96+
continue
97+
}
98+
cfgs[user] = c.GetVersionedRulesConfig()
99+
}
100+
return cfgs, nil
101+
}

pkg/configs/db/postgres/postgres.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,71 @@ func (d DB) GetConfigs(since configs.ID) (map[string]configs.View, error) {
134134
})
135135
}
136136

137+
// GetRulesConfig gets the latest alertmanager config for a user.
138+
func (d DB) GetRulesConfig(userID string) (configs.VersionedRulesConfig, error) {
139+
current, err := d.GetConfig(userID)
140+
if err != nil {
141+
return configs.VersionedRulesConfig{}, err
142+
}
143+
return current.GetVersionedRulesConfig(), nil
144+
}
145+
146+
// SetRulesConfig sets the current alertmanager config for a user.
147+
func (d DB) SetRulesConfig(userID string, config configs.RulesConfig) error {
148+
current, err := d.GetConfig(userID)
149+
if err != nil {
150+
return err
151+
}
152+
new := configs.Config{
153+
AlertmanagerConfig: current.Config.AlertmanagerConfig,
154+
RulesFiles: config,
155+
}
156+
return d.SetConfig(userID, new)
157+
}
158+
159+
func (d DB) findRulesConfigs(filter squirrel.Sqlizer) (map[string]configs.VersionedRulesConfig, error) {
160+
rows, err := d.Select("id", "owner_id", "config ->> 'rules_files'").
161+
Options("DISTINCT ON (owner_id)").
162+
From("configs").
163+
Where(filter).
164+
Where("config ->> 'rules_files' <> '{}'").
165+
OrderBy("owner_id, id DESC").
166+
Query()
167+
if err != nil {
168+
return nil, err
169+
}
170+
defer rows.Close()
171+
cfgs := map[string]configs.VersionedRulesConfig{}
172+
for rows.Next() {
173+
var cfg configs.VersionedRulesConfig
174+
var userID string
175+
var cfgBytes []byte
176+
err = rows.Scan(&cfg.ID, &userID, &cfgBytes)
177+
if err != nil {
178+
return nil, err
179+
}
180+
err = json.Unmarshal(cfgBytes, &cfg.Config)
181+
if err != nil {
182+
return nil, err
183+
}
184+
cfgs[userID] = cfg
185+
}
186+
return cfgs, nil
187+
}
188+
189+
// GetAllRulesConfigs gets all alertmanager configs for all users.
190+
func (d DB) GetAllRulesConfigs() (map[string]configs.VersionedRulesConfig, error) {
191+
return d.findRulesConfigs(activeConfig)
192+
}
193+
194+
// GetRulesConfigs gets all the alertmanager configs that have changed since a given config.
195+
func (d DB) GetRulesConfigs(since configs.ID) (map[string]configs.VersionedRulesConfig, error) {
196+
return d.findRulesConfigs(squirrel.And{
197+
activeConfig,
198+
squirrel.Gt{"id": since},
199+
})
200+
}
201+
137202
// Transaction runs the given function in a postgres transaction. If fn returns
138203
// an error the txn will be rolled back.
139204
func (d DB) Transaction(f func(DB) error) error {

pkg/configs/db/timed.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,33 @@ func (t timed) Close() error {
7474
return t.d.Close()
7575
})
7676
}
77+
78+
func (t timed) GetRulesConfig(userID string) (cfg configs.VersionedRulesConfig, err error) {
79+
t.timeRequest("GetRulesConfig", func(_ context.Context) error {
80+
cfg, err = t.d.GetRulesConfig(userID)
81+
return err
82+
})
83+
return
84+
}
85+
86+
func (t timed) SetRulesConfig(userID string, cfg configs.RulesConfig) (err error) {
87+
return t.timeRequest("SetRulesConfig", func(_ context.Context) error {
88+
return t.d.SetRulesConfig(userID, cfg)
89+
})
90+
}
91+
92+
func (t timed) GetAllRulesConfigs() (cfgs map[string]configs.VersionedRulesConfig, err error) {
93+
t.timeRequest("GetAllRulesConfigs", func(_ context.Context) error {
94+
cfgs, err = t.d.GetAllRulesConfigs()
95+
return err
96+
})
97+
return
98+
}
99+
100+
func (t timed) GetRulesConfigs(since configs.ID) (cfgs map[string]configs.VersionedRulesConfig, err error) {
101+
t.timeRequest("GetRulesConfigs", func(_ context.Context) error {
102+
cfgs, err = t.d.GetRulesConfigs(since)
103+
return err
104+
})
105+
return
106+
}

pkg/configs/db/traced.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,23 @@ func (t traced) Close() (err error) {
4141
defer func() { t.trace("Close", err) }()
4242
return t.d.Close()
4343
}
44+
45+
func (t traced) GetRulesConfig(userID string) (cfg configs.VersionedRulesConfig, err error) {
46+
defer func() { t.trace("GetRulesConfig", userID, cfg, err) }()
47+
return t.d.GetRulesConfig(userID)
48+
}
49+
50+
func (t traced) SetRulesConfig(userID string, cfg configs.RulesConfig) (err error) {
51+
defer func() { t.trace("SetRulesConfig", userID, cfg, err) }()
52+
return t.d.SetRulesConfig(userID, cfg)
53+
}
54+
55+
func (t traced) GetAllRulesConfigs() (cfgs map[string]configs.VersionedRulesConfig, err error) {
56+
defer func() { t.trace("GetAllRulesConfigs", cfgs, err) }()
57+
return t.d.GetAllRulesConfigs()
58+
}
59+
60+
func (t traced) GetRulesConfigs(since configs.ID) (cfgs map[string]configs.VersionedRulesConfig, err error) {
61+
defer func() { t.trace("GetConfigs", since, cfgs, err) }()
62+
return t.d.GetRulesConfigs(since)
63+
}

0 commit comments

Comments
 (0)