Skip to content
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

WIP: Add ability to define custom entries in pg_ident.conf #753

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
11 changes: 11 additions & 0 deletions cmd/keeper/cmd/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -1058,6 +1058,7 @@ func (p *PostgresKeeper) postgresKeeperSM(pctx context.Context) {

// Generate hba auth from clusterData
pgm.SetHba(p.generateHBA(cd, db, p.waitSyncStandbysSynced))
pgm.SetIdent(db.Spec.PgIdent)

var pgParameters common.Parameters

Expand Down Expand Up @@ -1475,6 +1476,7 @@ func (p *PostgresKeeper) postgresKeeperSM(pctx context.Context) {
p.waitSyncStandbysSynced = true
log.Infow("not allowing connection as normal users since synchronous replication is enabled and instance was down")
pgm.SetHba(p.generateHBA(cd, db, true))
pgm.SetIdent(db.Spec.PgIdent)
}

if err = pgm.Start(); err != nil {
Expand Down Expand Up @@ -1657,6 +1659,15 @@ func (p *PostgresKeeper) postgresKeeperSM(pctx context.Context) {
// for tests
log.Infow("postgres hba entries not changed")
}
newIdent := db.Spec.PgIdent
if !reflect.DeepEqual(newIdent, pgm.CurIdent()) {
log.Infow("postgres ident entries changed, reloading postgres instance")
pgm.SetIdent(newIdent)
needsReload = true
} else {
// for tests
log.Infow("postgres ident entries not changed")
}

if needsReload {
needsReloadGauge.Set(1) // mark as reload needed
Expand Down
1 change: 1 addition & 0 deletions cmd/sentinel/cmd/sentinel.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ func (s *Sentinel) setDBSpecFromClusterSpec(cd *cluster.ClusterData) {
db.Spec.UsePgrewind = *clusterSpec.UsePgrewind
db.Spec.PGParameters = clusterSpec.PGParameters
db.Spec.PGHBA = clusterSpec.PGHBA
db.Spec.PgIdent = clusterSpec.PgIdent
if db.Spec.FollowConfig != nil && db.Spec.FollowConfig.Type == cluster.FollowTypeExternal {
db.Spec.FollowConfig.StandbySettings = clusterSpec.StandbyConfig.StandbySettings
db.Spec.FollowConfig.ArchiveRecoverySettings = clusterSpec.StandbyConfig.ArchiveRecoverySettings
Expand Down
3 changes: 3 additions & 0 deletions cmd/stolonctl/cmd/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (

cmdcommon "github.com/sorintlab/stolon/cmd"
"github.com/sorintlab/stolon/internal/cluster"
"github.com/sorintlab/stolon/internal/postgresql"

"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -69,6 +70,7 @@ type ClusterSpecNoDefaults struct {
DefaultSUReplAccessMode *cluster.SUReplAccessMode `json:"defaultSUReplAccessMode,omitempty"`
PGParameters cluster.PGParameters `json:"pgParameters,omitempty"`
PGHBA []string `json:"pgHBA,omitempty"`
PgIdent postgresql.PgIdent `json:"pgIdent"`
AutomaticPgRestart *bool `json:"automaticPgRestart,omitempty"`
}

Expand Down Expand Up @@ -100,6 +102,7 @@ type ClusterSpecDefaults struct {
DefaultSUReplAccessMode *cluster.SUReplAccessMode `json:"defaultSUReplAccessMode"`
PGParameters cluster.PGParameters `json:"pgParameters"`
PGHBA []string `json:"pgHBA"`
PgIdent postgresql.PgIdent `json:"pgIdent"`
AutomaticPgRestart *bool `json:"automaticPgRestart"`
}

Expand Down
4 changes: 4 additions & 0 deletions internal/cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ type ClusterSpec struct {
// Additional pg_hba.conf entries
// we don't set omitempty since we want to distinguish between null or empty slice
PGHBA []string `json:"pgHBA"`
// pg_ident.conf entries
PgIdent util.PgIdent `json:"pgIdent"`
// Enable automatic pg restart when pg parameters that requires restart changes
AutomaticPgRestart *bool `json:"automaticPgRestart"`
}
Expand Down Expand Up @@ -625,6 +627,8 @@ type DBSpec struct {
// Additional pg_hba.conf entries
// We don't set omitempty since we want to distinguish between null or empty slice
PGHBA []string `json:"pgHBA"`
// pg_ident.conf entries
PgIdent util.PgIdent `json:"pgIdent"`
// DB Role (master or standby)
Role common.Role `json:"role,omitempty"`
// FollowConfig when Role is "standby"
Expand Down
49 changes: 49 additions & 0 deletions internal/postgresql/postgresql.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ var (

var log = slog.S()

type PgIdent map[string][]UserMaps

type UserMaps struct {
SystemUsername string `json:"systemUsername"`
DBUsername string `json:"databaseUsername"`
}

type PGManager interface {
GetTimelinesHistory(timeline uint64) ([]*TimelineHistory, error)
}
Expand All @@ -69,6 +76,8 @@ type Manager struct {
parameters common.Parameters
recoveryOptions *RecoveryOptions
hba []string
ident PgIdent
currentIdent PgIdent
curParameters common.Parameters
curRecoveryOptions *RecoveryOptions
curHba []string
Expand Down Expand Up @@ -178,10 +187,18 @@ func (p *Manager) SetHba(hba []string) {
p.hba = hba
}

func (p *Manager) SetIdent(ident PgIdent) {
p.ident = ident
}

func (p *Manager) CurHba() []string {
return p.curHba
}

func (p *Manager) CurIdent() PgIdent {
return p.currentIdent
}

func (p *Manager) UpdateCurParameters() {
n, err := copystructure.Copy(p.parameters)
if err != nil {
Expand All @@ -202,6 +219,14 @@ func (p *Manager) UpdateCurHba() {
p.curHba = n.([]string)
}

func (p *Manager) UpdateCurIdent() {
n, err := copystructure.Copy(p.ident)
if err != nil {
panic(err)
}
p.currentIdent = n.(PgIdent)
}

func (p *Manager) Init(initConfig *InitConfig) error {
// ioutil.Tempfile already creates files with 0600 permissions
pwfile, err := ioutil.TempFile("", "pwfile")
Expand Down Expand Up @@ -374,6 +399,7 @@ func (p *Manager) start(args ...string) error {
p.UpdateCurParameters()
p.UpdateCurRecoveryOptions()
p.UpdateCurHba()
p.UpdateCurIdent()

return nil
}
Expand Down Expand Up @@ -438,6 +464,7 @@ func (p *Manager) Reload() error {
p.UpdateCurParameters()
p.UpdateCurRecoveryOptions()
p.UpdateCurHba()
p.UpdateCurIdent()

return nil
}
Expand Down Expand Up @@ -767,6 +794,9 @@ func (p *Manager) writeConfs(useTmpPostgresConf bool) error {
return fmt.Errorf("error writing %s file: %v", postgresRecoverySignal, err)
}
}
if err := p.writePgIdent(); err != nil {
return fmt.Errorf("error writing pg_ident.conf file: %v", err)
}
return nil
}

Expand Down Expand Up @@ -877,6 +907,25 @@ func (p *Manager) writePgHba() error {
})
}

func (p *Manager) writePgIdent() error {
return common.WriteFileAtomicFunc(filepath.Join(p.dataDir, "pg_ident.conf"), 0600,
func(f io.Writer) error {
if p.ident != nil && len(p.ident) > 0 {
if _, err := f.Write([]byte("# MAPNAME\tSYSTEM-USERNAME\tPG-USERNAME" + "\n")); err != nil {
return err
}
for key, value := range p.ident {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Entries will likely be written out in an undefined order (https://go.dev/blog/maps#iteration-order) - sorting the entries before writing them out might be beneficial

for _, v := range value {
if _, err := f.Write([]byte(fmt.Sprintf("%s\t%s\t%s", key, v.SystemUsername, v.DBUsername) + "\n")); err != nil {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

f is an os.File which doesn't guarantee full writes

return err
}
}
}
}
return nil
})
}

// createPostgresqlAutoConf creates postgresql.auto.conf as a symlink to
// /dev/null to block alter systems commands (they'll return an error)
func (p *Manager) createPostgresqlAutoConf() error {
Expand Down