Add read-write, read-only and primary routes
This commit is contained in:
parent
950777f5bc
commit
ccf95c6f86
3 changed files with 54 additions and 3 deletions
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
1.1.0
|
1.2.0
|
||||||
|
|
|
@ -10,7 +10,9 @@ import (
|
||||||
// and forward requests from frontend
|
// and forward requests from frontend
|
||||||
type Backend interface {
|
type Backend interface {
|
||||||
IsPrimary() (bool, error)
|
IsPrimary() (bool, error)
|
||||||
|
IsReadWrite() (bool, error)
|
||||||
IsReplica() (bool, error)
|
IsReplica() (bool, error)
|
||||||
|
IsReadOnly() (bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBackend creates a backend from a driver, a connection string
|
// NewBackend creates a backend from a driver, a connection string
|
||||||
|
@ -90,12 +92,22 @@ func (b HTTPBackend) request(key string) (bool, error) {
|
||||||
return state.(bool), nil
|
return state.(bool), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsPrimary will call /master route on patroni API
|
// IsPrimary will call /primary route on patroni API
|
||||||
func (b HTTPBackend) IsPrimary() (bool, error) {
|
func (b HTTPBackend) IsPrimary() (bool, error) {
|
||||||
return b.request("master")
|
return b.request("primary")
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsReadWrite will call /read-write route on patroni API
|
||||||
|
func (b HTTPBackend) IsReadWrite() (bool, error) {
|
||||||
|
return b.request("read-write")
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsReplica will call /replica route on patroni API
|
// IsReplica will call /replica route on patroni API
|
||||||
func (b HTTPBackend) IsReplica() (bool, error) {
|
func (b HTTPBackend) IsReplica() (bool, error) {
|
||||||
return b.request("replica")
|
return b.request("replica")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsReadOnly will call /read-only route on patroni API
|
||||||
|
func (b HTTPBackend) IsReadOnly() (bool, error) {
|
||||||
|
return b.request("read-only")
|
||||||
|
}
|
||||||
|
|
|
@ -34,7 +34,10 @@ func (f *Frontend) Start() error {
|
||||||
Debug("registering routes")
|
Debug("registering routes")
|
||||||
r.HandleFunc("/health", HealthHandler).Methods("GET")
|
r.HandleFunc("/health", HealthHandler).Methods("GET")
|
||||||
r.HandleFunc("/master", PrimaryHandler).Methods("GET", "OPTIONS")
|
r.HandleFunc("/master", PrimaryHandler).Methods("GET", "OPTIONS")
|
||||||
|
r.HandleFunc("/primary", PrimaryHandler).Methods("GET", "OPTIONS")
|
||||||
|
r.HandleFunc("/read-write", ReadWriteHandler).Methods("GET", "OPTIONS")
|
||||||
r.HandleFunc("/replica", ReplicaHandler).Methods("GET", "OPTIONS")
|
r.HandleFunc("/replica", ReplicaHandler).Methods("GET", "OPTIONS")
|
||||||
|
r.HandleFunc("/read-only", ReadOnlyHandler).Methods("GET", "OPTIONS")
|
||||||
|
|
||||||
Info("listening on %s", f)
|
Info("listening on %s", f)
|
||||||
var err error
|
var err error
|
||||||
|
@ -148,6 +151,24 @@ func PrimaryHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
io.WriteString(w, message)
|
io.WriteString(w, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadWriteHandler exposes read-write status
|
||||||
|
func ReadWriteHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var message string
|
||||||
|
var status int
|
||||||
|
readWrite, err := backend.IsReadWrite()
|
||||||
|
if err != nil {
|
||||||
|
message = fmt.Sprintf("{\"error\":\"%v\"}", err)
|
||||||
|
status = http.StatusServiceUnavailable
|
||||||
|
}
|
||||||
|
message = fmt.Sprintf("{\"read-write\":%t}", readWrite)
|
||||||
|
status = http.StatusServiceUnavailable
|
||||||
|
if readWrite {
|
||||||
|
status = http.StatusOK
|
||||||
|
}
|
||||||
|
w.WriteHeader(status)
|
||||||
|
io.WriteString(w, message)
|
||||||
|
}
|
||||||
|
|
||||||
// ReplicaHandler exposes replica status
|
// ReplicaHandler exposes replica status
|
||||||
func ReplicaHandler(w http.ResponseWriter, r *http.Request) {
|
func ReplicaHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
var message string
|
var message string
|
||||||
|
@ -166,6 +187,24 @@ func ReplicaHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
io.WriteString(w, message)
|
io.WriteString(w, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadOnlyHandler exposes read-only status
|
||||||
|
func ReadOnlyHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var message string
|
||||||
|
var status int
|
||||||
|
readOnly, err := backend.IsReadOnly()
|
||||||
|
if err != nil {
|
||||||
|
message = fmt.Sprintf("{\"error\":\"%v\"}", err)
|
||||||
|
status = http.StatusServiceUnavailable
|
||||||
|
}
|
||||||
|
message = fmt.Sprintf("{\"read-only\":%t}", readOnly)
|
||||||
|
status = http.StatusServiceUnavailable
|
||||||
|
if readOnly {
|
||||||
|
status = http.StatusOK
|
||||||
|
}
|
||||||
|
w.WriteHeader(status)
|
||||||
|
io.WriteString(w, message)
|
||||||
|
}
|
||||||
|
|
||||||
// Store TLS ciphers map from string to constant
|
// Store TLS ciphers map from string to constant
|
||||||
// See full list at https://golang.org/pkg/crypto/tls/#pkg-constants
|
// See full list at https://golang.org/pkg/crypto/tls/#pkg-constants
|
||||||
var tlsCiphers = map[string]uint16{
|
var tlsCiphers = map[string]uint16{
|
||||||
|
|
Reference in a new issue