migrated to external IP allocator
This commit is contained in:
parent
8672452033
commit
e2449b425e
15 changed files with 478 additions and 194 deletions
|
|
@ -83,3 +83,16 @@ func (c *Client) DeleteLoadBalancer(ctx context.Context, cluster, name string) (
|
|||
_, err = c.c.Do(req, nil)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Client) DeleteLoadBalancersWithCluster(ctx context.Context, cluster string) (err error) {
|
||||
if cluster == "" {
|
||||
return errors.New("cluster value can not be empty")
|
||||
}
|
||||
path := base + "/lb/" + cluster
|
||||
req, err := c.c.NewRequest(ctx, "DELETE", path, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, err = c.c.Do(req, nil)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
/*
|
||||
|
|
@ -16,8 +17,15 @@ const Version = "v1"
|
|||
type LoadBalancer struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
IP string `json:"ip,omitempty"`
|
||||
CIDR string `json:"cidr,omitempty"`
|
||||
Options Options `json:"options,omitempty"`
|
||||
Ports []Port `json:"ports,omitempty"`
|
||||
Ports Ports `json:"ports,omitempty"`
|
||||
}
|
||||
|
||||
func NewLoadBalancerFromBytes(b []byte) (lb *LoadBalancer, err error) {
|
||||
lb = new(LoadBalancer)
|
||||
err = json.Unmarshal(b, lb)
|
||||
return
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
|
|
@ -29,16 +37,83 @@ type Options struct {
|
|||
}
|
||||
|
||||
type Port struct {
|
||||
Port int `json:"port,omitempty"`
|
||||
Servers []Server `json:"servers,omitempty"`
|
||||
Port int `json:"port,omitempty"`
|
||||
Servers Servers `json:"servers,omitempty"`
|
||||
}
|
||||
|
||||
type Ports []Port
|
||||
|
||||
func (p Ports) Len() int { return len(p) }
|
||||
func (p Ports) Less(i, j int) bool { return p[i].Port < p[j].Port }
|
||||
func (p Ports) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
|
||||
type Server struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
IP string `json:"ip,omitempty"`
|
||||
Port int `json:"port,omitempty"`
|
||||
}
|
||||
|
||||
type Servers []Server
|
||||
|
||||
func (s Servers) Len() int { return len(s) }
|
||||
func (s Servers) Less(i, j int) bool { return s[i].Name < s[j].Name }
|
||||
func (s Servers) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
func (o Servers) Equal(n Servers) bool {
|
||||
if len(o) != len(n) {
|
||||
return false
|
||||
}
|
||||
for i, v := range o {
|
||||
if v.Name != n[i].Name ||
|
||||
v.IP != n[i].IP ||
|
||||
v.Port != n[i].Port {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (o Servers) ContainsIP(ip string) bool {
|
||||
return o.IndexOfIP(ip) != -1
|
||||
}
|
||||
|
||||
func (o Servers) IndexOfIP(ip string) int {
|
||||
for i, v := range o {
|
||||
if v.IP == ip {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (o Servers) RemoveByIP(ip string) Servers {
|
||||
index := o.IndexOfIP(ip)
|
||||
if index == -1 {
|
||||
return o
|
||||
}
|
||||
return append(o[:index], o[index+1:]...)
|
||||
}
|
||||
|
||||
func (o Servers) ContainsName(name string) bool {
|
||||
return o.IndexOfName(name) != -1
|
||||
}
|
||||
|
||||
func (o Servers) IndexOfName(name string) int {
|
||||
for i, v := range o {
|
||||
if v.Name == name {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
func (o Servers) RemoveByName(name string) Servers {
|
||||
index := o.IndexOfName(name)
|
||||
if index == -1 {
|
||||
return o
|
||||
}
|
||||
return append(o[:index], o[index+1:]...)
|
||||
}
|
||||
|
||||
func (lb LoadBalancer) ValidateClient() error {
|
||||
for i, p := range lb.Ports {
|
||||
if p.Port < 0 || p.Port > 65535 {
|
||||
|
|
@ -66,7 +141,18 @@ func (lb LoadBalancer) ValidateServer() error {
|
|||
if lb.IP == "" {
|
||||
return errors.New("LoadBalancer.IP can not be empty")
|
||||
}
|
||||
return lb.ValidateClient()
|
||||
if lb.CIDR == "" {
|
||||
return errors.New("LoadBalancer.CIDR can not be empty")
|
||||
}
|
||||
err := lb.ValidateClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sort.Sort(lb.Ports)
|
||||
for _, p := range lb.Ports {
|
||||
sort.Sort(p.Servers)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (lb LoadBalancer) JSON() ([]byte, error) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package server
|
|||
import (
|
||||
//"golang.org/x/crypto/bcrypt"
|
||||
//"net/http"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net"
|
||||
|
||||
|
|
@ -80,13 +79,14 @@ func lbHandler(ctx *types.Context) {
|
|||
return
|
||||
}
|
||||
lb.Name = lbname(cl, n)
|
||||
cidr, err := ctx.Data.DB.GetIP(name)
|
||||
cidr, err := ctx.Data.DB.GetCIDR(name)
|
||||
if err != nil && err != cluster.ErrKeyNotFound {
|
||||
ctx.Log.Error(err, "error getting existing loadbalancer ip", "cluster", cl, "name", n)
|
||||
ctx.Err(types.ErrISE)
|
||||
return
|
||||
}
|
||||
if cidr != "" {
|
||||
lb.CIDR = cidr
|
||||
lb.IP, err = getIP(cidr)
|
||||
if err != nil {
|
||||
ctx.Log.Error(err, "error parsing existing ip", "cluster", cl, "name", n, "cidr", cidr)
|
||||
|
|
@ -94,12 +94,14 @@ func lbHandler(ctx *types.Context) {
|
|||
return
|
||||
}
|
||||
} else {
|
||||
lb.IP, err = ctx.Data.Alloc.AllocIP(context.Background(), name)
|
||||
ip, err := ctx.Data.Net.Alloc()
|
||||
if err != nil {
|
||||
ctx.Log.Error(err, "error allocating ip for loadbalancer", "cluster", cl, "name", n)
|
||||
ctx.Err(types.ErrISE)
|
||||
return
|
||||
}
|
||||
lb.IP = ip.IP.String()
|
||||
lb.CIDR = ctx.Data.Net.CIDR(ip)
|
||||
}
|
||||
err = lb.ValidateServer()
|
||||
if err != nil {
|
||||
|
|
@ -125,7 +127,13 @@ func lbHandler(ctx *types.Context) {
|
|||
ctx.Err(types.ErrNotFound)
|
||||
return
|
||||
}
|
||||
err := ctx.Data.Alloc.FreeIP(context.Background(), name)
|
||||
cidr, err := ctx.Data.DB.GetCIDR(name)
|
||||
if err != nil && err != cluster.ErrKeyNotFound {
|
||||
ctx.Log.Error(err, "error reading IP of loadbalancer", "cluster", cl, "name", n)
|
||||
ctx.Err(types.ErrISE)
|
||||
return
|
||||
}
|
||||
err = ctx.Data.Net.FreeCIDR(cidr)
|
||||
if err != nil && err != cluster.ErrKeyNotFound {
|
||||
ctx.Log.Error(err, "error freeing IP of loadbalancer", "cluster", cl, "name", n)
|
||||
ctx.Err(types.ErrISE)
|
||||
|
|
@ -149,20 +157,45 @@ func lbList(lbs map[string][]byte) (m map[string]json.RawMessage) {
|
|||
return
|
||||
}
|
||||
|
||||
func lbClusterListHandler(ctx *types.Context) {
|
||||
func lbClusterHandler(ctx *types.Context) {
|
||||
cl := ctx.Var("cluster")
|
||||
m, err := ctx.Data.DB.GetLBs(cl)
|
||||
if err != nil {
|
||||
ctx.Log.Error(err, "error reading loadbalancers")
|
||||
ctx.Log.Error(err, "error reading loadbalancers", "cluster", cl)
|
||||
ctx.Err(types.ErrISE)
|
||||
return
|
||||
}
|
||||
ctx.JSON(lbList(m))
|
||||
switch ctx.Method() {
|
||||
case "GET":
|
||||
ctx.JSON(lbList(m))
|
||||
case "DELETE":
|
||||
for name, _ := range m {
|
||||
cidr, err := ctx.Data.DB.GetCIDR(name)
|
||||
if err != nil && err != cluster.ErrKeyNotFound {
|
||||
ctx.Log.Error(err, "error reading IP of loadbalancer", "cluster", cl, "name", name)
|
||||
ctx.Err(types.ErrISE)
|
||||
return
|
||||
}
|
||||
err = ctx.Data.Net.FreeCIDR(cidr)
|
||||
if err != nil && err != cluster.ErrKeyNotFound {
|
||||
ctx.Log.Error(err, "error freeing IP of loadbalancer", "cluster", cl, "name", name)
|
||||
ctx.Err(types.ErrISE)
|
||||
return
|
||||
}
|
||||
err = ctx.Data.DB.DeleteLB(name)
|
||||
if err != nil {
|
||||
ctx.Log.Error(err, "error deleting loadbalancer", "cluster", cl, "name", name)
|
||||
ctx.Err(types.ErrISE)
|
||||
return
|
||||
}
|
||||
}
|
||||
ctx.OK()
|
||||
}
|
||||
}
|
||||
func lbListHandler(ctx *types.Context) {
|
||||
m, err := ctx.Data.DB.GetLBs("")
|
||||
if err != nil {
|
||||
ctx.Log.Error(err, "error reading loadbalancers")
|
||||
ctx.Log.Error(err, "error reading loadbalancer clusters")
|
||||
ctx.Err(types.ErrISE)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ var Routes = []types.Route{
|
|||
},
|
||||
{
|
||||
v1 + "/lb/{cluster:[a-zA-Z0-9-]+$}",
|
||||
authHandler(lbClusterListHandler),
|
||||
[]string{"GET"},
|
||||
authHandler(lbClusterHandler),
|
||||
[]string{"GET", "DELETE"},
|
||||
},
|
||||
{
|
||||
v1 + "/lb/{cluster:[a-zA-Z0-9-]+}/{name:[a-zA-Z0-9-_]+$}",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue