Use Patroni API to set bootstrap-only options. (#299)

Call Patroni API /config in order to set special options that are
ignored when set in the configuration file, such as max_connections.
Per https://github.com/zalando-incubator/postgres-operator/issues/297

* Some minor refacoring:

Rename Cluster ManualFailover to Swithover
Rename Patroni Failover to Switchover
Add more details to error messages and comments introduced in this PR.

Review by @zerg-junior
This commit is contained in:
Oleksii Kliukin
2018-05-29 12:35:25 +02:00
committed by GitHub
parent 24df918dda
commit 48a5744314
6 changed files with 85 additions and 17 deletions
+28 -11
View File
@@ -14,13 +14,15 @@ import (
const (
failoverPath = "/failover"
configPath = "/config"
apiPort = 8008
timeout = 30 * time.Second
)
// Interface describe patroni methods
type Interface interface {
Failover(master *v1.Pod, candidate string) error
Switchover(master *v1.Pod, candidate string) error
SetPostgresParameters(server *v1.Pod, options map[string]string) error
}
// Patroni API client
@@ -45,20 +47,13 @@ func apiURL(masterPod *v1.Pod) string {
return fmt.Sprintf("http://%s:%d", masterPod.Status.PodIP, apiPort)
}
// Failover does manual failover via patroni api
func (p *Patroni) Failover(master *v1.Pod, candidate string) error {
buf := &bytes.Buffer{}
err := json.NewEncoder(buf).Encode(map[string]string{"leader": master.Name, "member": candidate})
if err != nil {
return fmt.Errorf("could not encode json: %v", err)
}
request, err := http.NewRequest(http.MethodPost, apiURL(master)+failoverPath, buf)
func (p *Patroni) httpPostOrPatch(method string, url string, body *bytes.Buffer) error {
request, err := http.NewRequest(method, url, body)
if err != nil {
return fmt.Errorf("could not create request: %v", err)
}
p.logger.Debugf("making http request: %s", request.URL.String())
p.logger.Debugf("making %s http request: %s", method, request.URL.String())
resp, err := p.httpClient.Do(request)
if err != nil {
@@ -74,6 +69,28 @@ func (p *Patroni) Failover(master *v1.Pod, candidate string) error {
return fmt.Errorf("patroni returned '%s'", string(bodyBytes))
}
return nil
}
// Switchover by calling Patroni REST API
func (p *Patroni) Switchover(master *v1.Pod, candidate string) error {
buf := &bytes.Buffer{}
err := json.NewEncoder(buf).Encode(map[string]string{"leader": master.Name, "member": candidate})
if err != nil {
return fmt.Errorf("could not encode json: %v", err)
}
return p.httpPostOrPatch(http.MethodPost, apiURL(master)+failoverPath, buf)
return nil
}
//TODO: add an option call /patroni to check if it is necessary to restart the server
// SetPostgresParameters sets Postgres options via Patroni patch API call.
func (p *Patroni) SetPostgresParameters(server *v1.Pod, parameters map[string]string) error {
buf := &bytes.Buffer{}
err := json.NewEncoder(buf).Encode(map[string]map[string]interface{}{"postgresql": {"parameters": parameters}})
if err != nil {
return fmt.Errorf("could not encode json: %v", err)
}
return p.httpPostOrPatch(http.MethodPatch, apiURL(server)+configPath, buf)
}