some api changes
This commit is contained in:
parent
f305f96195
commit
70fd3f71e5
11 changed files with 118 additions and 76 deletions
|
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
@ -14,10 +15,12 @@ import (
|
||||||
"git.giftfish.de/ston1th/haproxy-lb/pkg/controller"
|
"git.giftfish.de/ston1th/haproxy-lb/pkg/controller"
|
||||||
"git.giftfish.de/ston1th/haproxy-lb/pkg/etcd"
|
"git.giftfish.de/ston1th/haproxy-lb/pkg/etcd"
|
||||||
"git.giftfish.de/ston1th/haproxy-lb/pkg/raft"
|
"git.giftfish.de/ston1th/haproxy-lb/pkg/raft"
|
||||||
"github.com/go-logr/logr"
|
|
||||||
|
|
||||||
//"github.com/iand/logfmtr"
|
//"github.com/iand/logfmtr"
|
||||||
"git.giftfish.de/ston1th/logfmtr"
|
//"git.giftfish.de/ston1th/logfmtr"
|
||||||
|
|
||||||
|
"github.com/go-logr/logr"
|
||||||
|
"github.com/go-logr/logr/funcr"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -34,42 +37,52 @@ func fatal(err error, msg string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
logopts := logfmtr.DefaultOptions()
|
//logopts := logfmtr.DefaultOptions()
|
||||||
logopts.TimestampFormat = "2006-01-02T15:04:05.000Z-0700"
|
//logopts.TimestampFormat = "2006-01-02T15:04:05.000Z-0700"
|
||||||
logopts.AddCaller = true
|
//logopts.AddCaller = true
|
||||||
logopts.CallerSkip = 1
|
//logopts.CallerSkip = 1
|
||||||
logopts.Timezone = true
|
//logopts.Timezone = true
|
||||||
logfmtr.UseOptions(logopts)
|
//logfmtr.UseOptions(logopts)
|
||||||
|
|
||||||
flag.IntVar(&verbosity, "v", verbosity, "number for the log level verbosity")
|
flag.IntVar(&verbosity, "v", verbosity, "number for the log level verbosity")
|
||||||
flag.StringVar(&configFile, "config", "haproxy-lb.yaml", "haproxy-lb config file")
|
flag.StringVar(&configFile, "config", "haproxy-lb.yaml", "haproxy-lb config file")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
logfmtr.SetVerbosity(verbosity)
|
//logfmtr.SetVerbosity(verbosity)
|
||||||
log = logfmtr.New().WithName("main")
|
//log = logfmtr.New()
|
||||||
|
|
||||||
log.Info("starting haproxy-lb", "version", version)
|
log = funcr.New(
|
||||||
|
func(pfx, args string) { fmt.Println("bla", pfx, args) },
|
||||||
|
funcr.Options{
|
||||||
|
LogCaller: funcr.All,
|
||||||
|
LogTimestamp: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
l := log.WithName("main")
|
||||||
|
|
||||||
|
l.Info("starting haproxy-lb", "version", version)
|
||||||
cfg, err := config.ParseFile(configFile)
|
cfg, err := config.ParseFile(configFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fatal(err, "init failed")
|
fatal(err, "config init failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
var c cluster.Cluster
|
var c cluster.Cluster
|
||||||
if cfg.Cluster.Raft != nil {
|
if cfg.Cluster.Raft != nil {
|
||||||
log.Info("creating cluster", "mode", "raft")
|
l.Info("creating cluster", "mode", "raft")
|
||||||
c = raft.NewCluster(logfmtr.New().WithName("raft"))
|
c = raft.NewCluster(log.WithName("raft"))
|
||||||
} else if cfg.Cluster.Etcd != nil {
|
} else if cfg.Cluster.Etcd != nil {
|
||||||
log.Info("creating cluster", "mode", "etcd")
|
l.Info("creating cluster", "mode", "etcd")
|
||||||
c = etcd.NewCluster(logfmtr.New().WithName("etcd"))
|
c = etcd.NewCluster(log.WithName("etcd"))
|
||||||
}
|
}
|
||||||
log.Info("starting api server", "address", cfg.APIServer.Listen, "tls", cfg.APIServer.TLS != nil, "auth", !cfg.APIServer.DisableAuth)
|
l.Info("starting api server", "address", cfg.APIServer.Listen, "tls", cfg.APIServer.TLS != nil, "auth", !cfg.APIServer.DisableAuth)
|
||||||
srv, err := api.NewServer(cfg, logfmtr.New().WithName("api"))
|
srv, err := api.NewServer(cfg, log.WithName("api"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fatal(err, "init failed")
|
fatal(err, "init failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("starting vip-controller")
|
l.Info("starting vip-controller")
|
||||||
callbacks, err := controller.NewLBController(cfg, srv, logfmtr.New().WithName("vip-controller"))
|
callbacks, err := controller.NewLBController(cfg, srv, log.WithName("vip-controller"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fatal(err, "init failed")
|
fatal(err, "init failed")
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +94,7 @@ func main() {
|
||||||
for {
|
for {
|
||||||
err = c.Start(cfg)
|
err = c.Start(cfg)
|
||||||
if err == cluster.ErrRestart {
|
if err == cluster.ErrRestart {
|
||||||
log.Error(err, "received restart signal. restarting cluster controller.")
|
l.Error(err, "received restart signal. restarting cluster controller.")
|
||||||
c.Reset()
|
c.Reset()
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
continue
|
continue
|
||||||
|
|
@ -102,16 +115,16 @@ func main() {
|
||||||
sigs := make(chan os.Signal, 1)
|
sigs := make(chan os.Signal, 1)
|
||||||
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
|
||||||
s := <-sigs
|
s := <-sigs
|
||||||
log.Info("haproxy-lb shutdown", "signal", s.String())
|
l.Info("haproxy-lb shutdown", "signal", s.String())
|
||||||
go func() {
|
go func() {
|
||||||
select {
|
select {
|
||||||
case <-time.After(time.Second * 20):
|
case <-time.After(time.Second * 20):
|
||||||
log.Error(errors.New("shutdown took longer than 20 seconds"), "shutdown forced")
|
l.Error(errors.New("shutdown took longer than 20 seconds"), "shutdown forced")
|
||||||
case <-sigs:
|
case <-sigs:
|
||||||
log.Error(errors.New("force shutdown triggerd"), "shutdown forced")
|
l.Error(errors.New("force shutdown triggerd"), "shutdown forced")
|
||||||
}
|
}
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}()
|
}()
|
||||||
c.Stop()
|
c.Stop()
|
||||||
log.Info("haproxy-lb stopped")
|
l.Info("haproxy-lb stopped")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ type Client struct {
|
||||||
endpoint string
|
endpoint string
|
||||||
username string
|
username string
|
||||||
password string
|
password string
|
||||||
|
auth bool
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
debugWriter io.Writer
|
debugWriter io.Writer
|
||||||
insecure bool
|
insecure bool
|
||||||
|
|
@ -62,6 +63,7 @@ func WithCredentials(username, password string) ClientOption {
|
||||||
return func(client *Client) {
|
return func(client *Client) {
|
||||||
client.username = username
|
client.username = username
|
||||||
client.password = password
|
client.password = password
|
||||||
|
client.auth = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,6 +79,7 @@ var (
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Endpoint string `json:"endpoint"`
|
Endpoint string `json:"endpoint"`
|
||||||
|
NoAuth bool `json:"no_auth"`
|
||||||
User string `json:"user"`
|
User string `json:"user"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
Insecure bool `json:"insecure"`
|
Insecure bool `json:"insecure"`
|
||||||
|
|
@ -87,6 +90,13 @@ func ClientOptionsFromConfig(cfg Config) (options []ClientOption, err error) {
|
||||||
err = ErrMissingEndpoint
|
err = ErrMissingEndpoint
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
options = []ClientOption{
|
||||||
|
WithEndpoint(cfg.Endpoint),
|
||||||
|
WithInsecureClient(cfg.Insecure),
|
||||||
|
}
|
||||||
|
if cfg.NoAuth {
|
||||||
|
return
|
||||||
|
}
|
||||||
if cfg.User == "" {
|
if cfg.User == "" {
|
||||||
err = ErrMissingUser
|
err = ErrMissingUser
|
||||||
return
|
return
|
||||||
|
|
@ -95,11 +105,7 @@ func ClientOptionsFromConfig(cfg Config) (options []ClientOption, err error) {
|
||||||
err = ErrMissingPassword
|
err = ErrMissingPassword
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
options = []ClientOption{
|
options = append(options, WithCredentials(cfg.User, cfg.Password))
|
||||||
WithEndpoint(cfg.Endpoint),
|
|
||||||
WithCredentials(cfg.User, cfg.Password),
|
|
||||||
WithInsecureClient(cfg.Insecure),
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -109,6 +115,17 @@ func ClientOptionsFromEnv() (options []ClientOption, err error) {
|
||||||
err = ErrMissingEndpointEnv
|
err = ErrMissingEndpointEnv
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
insecure, _ := strconv.ParseBool(os.Getenv("HAPROXY_LB_INSECURE"))
|
||||||
|
|
||||||
|
options = []ClientOption{
|
||||||
|
WithEndpoint(endpoint),
|
||||||
|
WithInsecureClient(insecure),
|
||||||
|
}
|
||||||
|
noAuth, _ := strconv.ParseBool(os.Getenv("HAPROXY_LB_NO_AUTH"))
|
||||||
|
if noAuth {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
user := os.Getenv("HAPROXY_LB_USER")
|
user := os.Getenv("HAPROXY_LB_USER")
|
||||||
if user == "" {
|
if user == "" {
|
||||||
err = ErrMissingUserEnv
|
err = ErrMissingUserEnv
|
||||||
|
|
@ -121,13 +138,7 @@ func ClientOptionsFromEnv() (options []ClientOption, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
insecure, _ := strconv.ParseBool(os.Getenv("HAPROXY_LB_INSECURE"))
|
options = append(options, WithCredentials(user, pass))
|
||||||
|
|
||||||
options = []ClientOption{
|
|
||||||
WithEndpoint(endpoint),
|
|
||||||
WithCredentials(user, pass),
|
|
||||||
WithInsecureClient(insecure),
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,7 +174,9 @@ func (c *Client) NewRequest(ctx context.Context, method, path string, body io.Re
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if c.auth {
|
||||||
req.SetBasicAuth(c.username, c.password)
|
req.SetBasicAuth(c.username, c.password)
|
||||||
|
}
|
||||||
req = req.WithContext(ctx)
|
req = req.WithContext(ctx)
|
||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,18 @@ package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Error struct {
|
type Error struct {
|
||||||
Message string `json:"message"`
|
Err string `json:"error"`
|
||||||
Status int `json:"status"`
|
Status int `json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e Error) Error() string {
|
||||||
|
return e.Err
|
||||||
|
}
|
||||||
|
|
||||||
func decodeResp(resp *http.Response, v interface{}) error {
|
func decodeResp(resp *http.Response, v interface{}) error {
|
||||||
if resp.Body == nil {
|
if resp.Body == nil {
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -22,16 +25,13 @@ func decodeResp(resp *http.Response, v interface{}) error {
|
||||||
}
|
}
|
||||||
return json.NewDecoder(resp.Body).Decode(&v)
|
return json.NewDecoder(resp.Body).Decode(&v)
|
||||||
}
|
}
|
||||||
if resp.StatusCode == 404 {
|
|
||||||
return ErrNotFound
|
|
||||||
}
|
|
||||||
var e Error
|
var e Error
|
||||||
err := json.NewDecoder(resp.Body).Decode(&e)
|
err := json.NewDecoder(resp.Body).Decode(&e)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if resp.StatusCode >= 400 && resp.StatusCode <= 599 {
|
if resp.StatusCode >= 400 && resp.StatusCode <= 599 {
|
||||||
return errors.New(e.Message)
|
return e
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ type notFoundHandler struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (nf *notFoundHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (nf *notFoundHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
types.NewContext(w, r, nf.s.Data, nf.s.log).NotFound()
|
types.NewContext(w, r, nf.s.Data, nf.s.log).Err(types.ErrInvalidAPIRoute)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHTTPServer returns a new HTTPServer
|
// NewHTTPServer returns a new HTTPServer
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ func (c *Context) log() {
|
||||||
c.Log.Info("access",
|
c.Log.Info("access",
|
||||||
"addr", c.Request.RemoteAddr,
|
"addr", c.Request.RemoteAddr,
|
||||||
"method", c.Request.Method,
|
"method", c.Request.Method,
|
||||||
"url", c.Request.URL.Path,
|
"path", c.Request.URL.Path,
|
||||||
"status", c.Status,
|
"status", c.Status,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ type Err struct {
|
||||||
|
|
||||||
// Error returns the error string
|
// Error returns the error string
|
||||||
func (a Err) Error() string {
|
func (a Err) Error() string {
|
||||||
return `{"message":"` + a.err + `","status":` + strconv.Itoa(a.status) + `}`
|
return `{"error":"` + a.err + `","status":` + strconv.Itoa(a.status) + `}`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status returns the HTTP status code
|
// Status returns the HTTP status code
|
||||||
|
|
@ -35,13 +35,17 @@ func newError(err string, status int) Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
ErrInvalidAPIRoute = newError("invalid api route", http.StatusNotFound)
|
||||||
ErrBadreq = newError("bad request", http.StatusBadRequest)
|
ErrBadreq = newError("bad request", http.StatusBadRequest)
|
||||||
ErrInvalid = newError("invalid data", http.StatusBadRequest)
|
ErrInvalid = newError("invalid data", http.StatusBadRequest)
|
||||||
ErrUnauthorized = newError("unauthorized", http.StatusUnauthorized)
|
ErrUnauthorized = newError("unauthorized", http.StatusUnauthorized)
|
||||||
ErrForbidden = newError("forbidden", http.StatusForbidden)
|
ErrForbidden = newError("forbidden", http.StatusForbidden)
|
||||||
ErrNotFound = newError("not found", http.StatusNotFound)
|
ErrNotFound = newError("not found", http.StatusNotFound)
|
||||||
|
ErrLBNotFound = newError("loadbalancer not found", http.StatusNotFound)
|
||||||
ErrMNA = newError("method not allowed", http.StatusMethodNotAllowed)
|
ErrMNA = newError("method not allowed", http.StatusMethodNotAllowed)
|
||||||
ErrExists = newError("resource already exists", http.StatusConflict)
|
ErrExists = newError("resource already exists", http.StatusConflict)
|
||||||
ErrISE = newError("internal server error", http.StatusInternalServerError)
|
ErrISE = newError("internal server error", http.StatusInternalServerError)
|
||||||
ErrFollower = newError("follower write forbidden", http.StatusForbidden)
|
ErrFollower = newError("follower write forbidden", http.StatusForbidden)
|
||||||
|
ErrClusterNotFound = newError("cluster not found", http.StatusNotFound)
|
||||||
|
ErrLBsNotFound = newError("loadbalancers not found", http.StatusNotFound)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrClientIsNil = errors.New("client is nil")
|
ErrClientIsNil = errors.New("client is nil")
|
||||||
base = "/" + schema.Version
|
base = schema.LBPath
|
||||||
)
|
)
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
|
|
@ -32,7 +32,7 @@ func (c *Client) GetLoadBalancers(ctx context.Context) (lbs map[string]schema.Lo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) GetLoadBalancersWithCluster(ctx context.Context, cluster string) (lbs map[string]schema.LoadBalancer, err error) {
|
func (c *Client) GetLoadBalancersWithCluster(ctx context.Context, cluster string) (lbs map[string]schema.LoadBalancer, err error) {
|
||||||
path := base + "/lb"
|
path := base
|
||||||
if cluster != "" {
|
if cluster != "" {
|
||||||
path += "/" + cluster
|
path += "/" + cluster
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +46,7 @@ func (c *Client) GetLoadBalancersWithCluster(ctx context.Context, cluster string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) GetLoadBalancer(ctx context.Context, cluster, name string) (lb schema.LoadBalancer, err error) {
|
func (c *Client) GetLoadBalancer(ctx context.Context, cluster, name string) (lb schema.LoadBalancer, err error) {
|
||||||
path := fmt.Sprintf("%s/lb/%s/%s", base, cluster, name)
|
path := fmt.Sprintf("%s/%s/%s", base, cluster, name)
|
||||||
req, err := c.c.NewRequest(ctx, "GET", path, nil)
|
req, err := c.c.NewRequest(ctx, "GET", path, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|
@ -57,7 +57,7 @@ func (c *Client) GetLoadBalancer(ctx context.Context, cluster, name string) (lb
|
||||||
|
|
||||||
func (c *Client) CreateLoadBalancer(ctx context.Context, cluster, name string, lb schema.LoadBalancer) (err error) {
|
func (c *Client) CreateLoadBalancer(ctx context.Context, cluster, name string, lb schema.LoadBalancer) (err error) {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
path := fmt.Sprintf("%s/lb/%s/%s", base, cluster, name)
|
path := fmt.Sprintf("%s/%s/%s", base, cluster, name)
|
||||||
err = lb.ValidateClient()
|
err = lb.ValidateClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|
@ -75,7 +75,7 @@ func (c *Client) CreateLoadBalancer(ctx context.Context, cluster, name string, l
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) DeleteLoadBalancer(ctx context.Context, cluster, name string) (err error) {
|
func (c *Client) DeleteLoadBalancer(ctx context.Context, cluster, name string) (err error) {
|
||||||
path := fmt.Sprintf("%s/lb/%s/%s", base, cluster, name)
|
path := fmt.Sprintf("%s/%s/%s", base, cluster, name)
|
||||||
req, err := c.c.NewRequest(ctx, "DELETE", path, nil)
|
req, err := c.c.NewRequest(ctx, "DELETE", path, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|
@ -88,7 +88,7 @@ func (c *Client) DeleteLoadBalancersWithCluster(ctx context.Context, cluster str
|
||||||
if cluster == "" {
|
if cluster == "" {
|
||||||
return errors.New("cluster value can not be empty")
|
return errors.New("cluster value can not be empty")
|
||||||
}
|
}
|
||||||
path := base + "/lb/" + cluster
|
path := base + "/" + cluster
|
||||||
req, err := c.c.NewRequest(ctx, "DELETE", path, nil)
|
req, err := c.c.NewRequest(ctx, "DELETE", path, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,11 @@ healthCheckNodePort
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const Version = "v1"
|
const (
|
||||||
|
Version = "v1"
|
||||||
|
LBName = "lb"
|
||||||
|
LBPath = "/" + Version + "/" + LBName
|
||||||
|
)
|
||||||
|
|
||||||
type ProxyProtocol string
|
type ProxyProtocol string
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ func lbHandler(ctx *types.Context) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Log.Error(err, "error reading loadbalancer", "cluster", cl, "name", n)
|
ctx.Log.Error(err, "error reading loadbalancer", "cluster", cl, "name", n)
|
||||||
if err == cluster.ErrKeyNotFound {
|
if err == cluster.ErrKeyNotFound {
|
||||||
ctx.Err(types.ErrNotFound)
|
ctx.Err(types.ErrLBNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Err(types.ErrISE)
|
ctx.Err(types.ErrISE)
|
||||||
|
|
@ -139,7 +139,7 @@ func lbHandler(ctx *types.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !ctx.Data.DB.LBExists(name) {
|
if !ctx.Data.DB.LBExists(name) {
|
||||||
ctx.Err(types.ErrNotFound)
|
ctx.Err(types.ErrLBNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cidr, err := ctx.Data.DB.GetCIDR(name)
|
cidr, err := ctx.Data.DB.GetCIDR(name)
|
||||||
|
|
@ -175,6 +175,10 @@ func lbList(lbs map[string][]byte) (m map[string]json.RawMessage) {
|
||||||
func lbClusterHandler(ctx *types.Context) {
|
func lbClusterHandler(ctx *types.Context) {
|
||||||
cl := ctx.Var("cluster")
|
cl := ctx.Var("cluster")
|
||||||
m, err := ctx.Data.DB.GetLBs(cl)
|
m, err := ctx.Data.DB.GetLBs(cl)
|
||||||
|
if err == cluster.ErrPrefixNotFound {
|
||||||
|
ctx.Err(types.ErrClusterNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Log.Error(err, "error reading loadbalancers", "cluster", cl)
|
ctx.Log.Error(err, "error reading loadbalancers", "cluster", cl)
|
||||||
ctx.Err(types.ErrISE)
|
ctx.Err(types.ErrISE)
|
||||||
|
|
@ -214,6 +218,10 @@ func lbClusterHandler(ctx *types.Context) {
|
||||||
}
|
}
|
||||||
func lbListHandler(ctx *types.Context) {
|
func lbListHandler(ctx *types.Context) {
|
||||||
m, err := ctx.Data.DB.GetLBs("")
|
m, err := ctx.Data.DB.GetLBs("")
|
||||||
|
if err == cluster.ErrPrefixNotFound {
|
||||||
|
ctx.Err(types.ErrLBsNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Log.Error(err, "error reading loadbalancer clusters")
|
ctx.Log.Error(err, "error reading loadbalancer clusters")
|
||||||
ctx.Err(types.ErrISE)
|
ctx.Err(types.ErrISE)
|
||||||
|
|
|
||||||
|
|
@ -2,29 +2,33 @@ package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.giftfish.de/ston1th/haproxy-lb/pkg/api/types"
|
"git.giftfish.de/ston1th/haproxy-lb/pkg/api/types"
|
||||||
schemav1 "git.giftfish.de/ston1th/haproxy-lb/pkg/api/v1/schema"
|
"git.giftfish.de/ston1th/haproxy-lb/pkg/api/v1/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
const v1 = "/" + schemav1.Version
|
const (
|
||||||
|
healthz = "/healthz"
|
||||||
|
lbcluster = schema.LBPath + "/{cluster:[a-zA-Z0-9-]+$}"
|
||||||
|
lbclustername = schema.LBPath + "/{cluster:[a-zA-Z0-9-]+}/{name:[a-zA-Z0-9-_]+$}"
|
||||||
|
)
|
||||||
|
|
||||||
var Routes = []types.Route{
|
var Routes = []types.Route{
|
||||||
{
|
{
|
||||||
"/healthz",
|
healthz,
|
||||||
healthzHandler,
|
healthzHandler,
|
||||||
[]string{"GET"},
|
[]string{"GET"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
v1 + "/lb",
|
schema.LBPath,
|
||||||
authHandler(lbListHandler),
|
authHandler(lbListHandler),
|
||||||
[]string{"GET"},
|
[]string{"GET"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
v1 + "/lb/{cluster:[a-zA-Z0-9-]+$}",
|
lbcluster,
|
||||||
authHandler(lbClusterHandler),
|
authHandler(lbClusterHandler),
|
||||||
[]string{"GET", "DELETE"},
|
[]string{"GET", "DELETE"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
v1 + "/lb/{cluster:[a-zA-Z0-9-]+}/{name:[a-zA-Z0-9-_]+$}",
|
lbclustername,
|
||||||
authHandler(lbHandler),
|
authHandler(lbHandler),
|
||||||
[]string{"GET", "POST", "DELETE"},
|
[]string{"GET", "POST", "DELETE"},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -86,10 +86,6 @@ func (db *DB) GetLBs(cl string) (lbs map[string][]byte, err error) {
|
||||||
cl = cl + "/"
|
cl = cl + "/"
|
||||||
}
|
}
|
||||||
m, err := db.kv.GetPrefix(lbPrefix + cl)
|
m, err := db.kv.GetPrefix(lbPrefix + cl)
|
||||||
if err == cluster.ErrPrefixNotFound {
|
|
||||||
err = nil
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue