Skip to content

Commit 701552a

Browse files
authored
Refactoring and adding more tests (#130)
* Adding tests * Revert rename * Cleanup * Fix lint * More lint fixes
1 parent 25f8a08 commit 701552a

File tree

13 files changed

+628
-495
lines changed

13 files changed

+628
-495
lines changed

internal/api/handle_admin.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ func handleUpdatePostgresSettings(w http.ResponseWriter, r *http.Request) {
189189
}}
190190
}
191191

192-
err = flypg.PushUserConfig(node.PGConfig, consul)
192+
err = flypg.PushUserConfig(&node.PGConfig, consul)
193193
if err != nil {
194194
renderErr(w, err)
195195
return
@@ -218,7 +218,7 @@ func handleApplyConfig(w http.ResponseWriter, r *http.Request) {
218218
return
219219
}
220220

221-
err = flypg.SyncUserConfig(node.PGConfig, consul)
221+
err = flypg.SyncUserConfig(&node.PGConfig, consul)
222222
if err != nil {
223223
renderErr(w, err)
224224
return

internal/flypg/admin/admin.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ import (
99
"github.com/jackc/pgx/v5"
1010
)
1111

12+
type Credential struct {
13+
Username string
14+
Password string
15+
}
16+
1217
func GrantAccess(ctx context.Context, pg *pgx.Conn, username string) error {
1318
sql := fmt.Sprintf("GRANT pg_read_all_data, pg_write_all_data TO %q", username)
1419
_, err := pg.Exec(ctx, sql)
@@ -28,6 +33,38 @@ func CreateUser(ctx context.Context, pg *pgx.Conn, username string, password str
2833
return err
2934
}
3035

36+
func ManageDefaultUsers(ctx context.Context, conn *pgx.Conn, creds []Credential) error {
37+
curUsers, err := ListUsers(ctx, conn)
38+
if err != nil {
39+
return fmt.Errorf("failed to list existing users: %s", err)
40+
}
41+
42+
for _, c := range creds {
43+
exists := false
44+
for _, curUser := range curUsers {
45+
if c.Username == curUser.Username {
46+
exists = true
47+
}
48+
}
49+
50+
if exists {
51+
if err := ChangePassword(ctx, conn, c.Username, c.Password); err != nil {
52+
return fmt.Errorf("failed to update credentials for user %s: %s", c.Username, err)
53+
}
54+
} else {
55+
if err := CreateUser(ctx, conn, c.Username, c.Password); err != nil {
56+
return fmt.Errorf("failed to create require user %s: %s", c.Username, err)
57+
}
58+
59+
if err := GrantSuperuser(ctx, conn, c.Username); err != nil {
60+
return fmt.Errorf("failed to grant superuser privileges to user %s: %s", c.Username, err)
61+
}
62+
}
63+
}
64+
65+
return nil
66+
}
67+
3168
func ChangePassword(ctx context.Context, pg *pgx.Conn, username, password string) error {
3269
sql := fmt.Sprintf("ALTER USER %s WITH LOGIN PASSWORD '%s';", username, password)
3370

internal/flypg/config.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ func PushUserConfig(c Config, consul *state.Store) error {
5252
}
5353

5454
func SyncUserConfig(c Config, consul *state.Store) error {
55+
if os.Getenv("UNIT_TESTING") != "" {
56+
return nil
57+
}
58+
5559
cfg, err := pullFromConsul(c, consul)
5660
if err != nil {
5761
return fmt.Errorf("failed to pull config from consul: %s", err)

internal/flypg/flypg.go

Lines changed: 10 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package flypg
22

33
import (
44
"fmt"
5-
"os"
65
"time"
76
)
87

@@ -12,25 +11,8 @@ type FlyPGConfig struct {
1211

1312
internalConfig ConfigMap
1413
userConfig ConfigMap
15-
16-
configPath string
1714
}
1815

19-
func (c *FlyPGConfig) SetDefaults() {
20-
c.internalConfig = ConfigMap{
21-
"deadMemberRemovalThreshold": time.Hour * 24,
22-
}
23-
}
24-
25-
func NewInternalConfig(configPath string) *FlyPGConfig {
26-
return &FlyPGConfig{
27-
internalConfigFilePath: fmt.Sprintf("%s/flypg.internal.conf", configPath),
28-
userConfigFilePath: fmt.Sprintf("%s/flypg.user.conf", configPath),
29-
configPath: configPath,
30-
internalConfig: ConfigMap{},
31-
userConfig: ConfigMap{},
32-
}
33-
}
3416
func (c *FlyPGConfig) InternalConfig() ConfigMap {
3517
return c.internalConfig
3618
}
@@ -55,6 +37,12 @@ func (c *FlyPGConfig) UserConfigFile() string {
5537
return c.userConfigFilePath
5638
}
5739

40+
func (c *FlyPGConfig) SetDefaults() {
41+
c.internalConfig = ConfigMap{
42+
"deadMemberRemovalThreshold": time.Hour * 24,
43+
}
44+
}
45+
5846
func (c *FlyPGConfig) CurrentConfig() (ConfigMap, error) {
5947
internal, err := ReadFromFile(c.InternalConfigFile())
6048
if err != nil {
@@ -80,28 +68,11 @@ func (c *FlyPGConfig) CurrentConfig() (ConfigMap, error) {
8068
func (c *FlyPGConfig) initialize() error {
8169
c.SetDefaults()
8270

83-
file, err := os.Create(c.internalConfigFilePath)
84-
if err != nil {
85-
return err
86-
}
87-
defer func() { _ = file.Close() }()
88-
89-
if err := file.Sync(); err != nil {
90-
return fmt.Errorf("failed to sync file: %s", err)
91-
} else if err := file.Close(); err != nil {
92-
return fmt.Errorf("failed to close file: %s", err)
93-
}
94-
95-
file, err = os.Create(c.userConfigFilePath)
96-
if err != nil {
97-
return err
98-
}
99-
defer func() { _ = file.Close() }()
71+
// Note - Sync from consul has been disabled for this component.
72+
// It will be re-enabled once we offer user-defined configuration.
10073

101-
if err := file.Sync(); err != nil {
102-
return fmt.Errorf("failed to sync file: %s", err)
103-
} else if err := file.Close(); err != nil {
104-
return fmt.Errorf("failed to close file: %s", err)
74+
if err := WriteConfigFiles(c); err != nil {
75+
return fmt.Errorf("failed to write internal config files: %s", err)
10576
}
10677

10778
return nil

internal/flypg/flypg_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package flypg
2+
3+
import (
4+
"testing"
5+
"time"
6+
7+
"github.com/fly-apps/postgres-flex/internal/utils"
8+
)
9+
10+
const (
11+
flyTestDirectory = "./test_results"
12+
flyInternalConfigFilePath = "./test_results/flypg.internal.conf"
13+
flyUserConfigFilePath = "./test_results/flypg.user.conf"
14+
)
15+
16+
func TestFlyConfigInitialization(t *testing.T) {
17+
if err := setup(t); err != nil {
18+
t.Fatal(err)
19+
}
20+
defer cleanup()
21+
22+
cfg := FlyPGConfig{
23+
internalConfigFilePath: flyInternalConfigFilePath,
24+
userConfigFilePath: flyInternalConfigFilePath,
25+
}
26+
27+
if err := cfg.initialize(); err != nil {
28+
t.Fatal(err)
29+
}
30+
31+
t.Run("configFiles", func(t *testing.T) {
32+
if !utils.FileExists(cfg.internalConfigFilePath) {
33+
t.Fatalf("expected %s to exist, but doesn't", cfg.internalConfigFilePath)
34+
}
35+
36+
if !utils.FileExists(cfg.userConfigFilePath) {
37+
t.Fatalf("expected %s to exist, but doesn't", cfg.userConfigFilePath)
38+
}
39+
})
40+
41+
t.Run("defaults", func(t *testing.T) {
42+
cfg, err := cfg.CurrentConfig()
43+
if err != nil {
44+
t.Fatal(err)
45+
}
46+
47+
if cfg["deadMemberRemovalThreshold"] != (24 * time.Hour).String() {
48+
t.Fatalf("expected deadMemberRemovalThreshold to be 24h, but got %v", cfg["deadMemberRemovalThreshold"])
49+
}
50+
})
51+
}

0 commit comments

Comments
 (0)