added loadbalancer
This commit is contained in:
parent
90c5f8e98e
commit
bd94056453
9 changed files with 371 additions and 113 deletions
|
|
@ -18,6 +18,8 @@ import (
|
|||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
lb "git.giftfish.de/ston1th/haproxy-lb/pkg/api/client"
|
||||
lbclient "git.giftfish.de/ston1th/haproxy-lb/pkg/api/v1/client"
|
||||
pve "git.giftfish.de/ston1th/pve-go"
|
||||
cloudprovider "k8s.io/cloud-provider"
|
||||
)
|
||||
|
|
@ -28,40 +30,66 @@ const (
|
|||
)
|
||||
|
||||
type cloud struct {
|
||||
client *pve.Client
|
||||
instances cloudprovider.Instances
|
||||
instancesV2 cloudprovider.InstancesV2
|
||||
pveClient *pve.Client
|
||||
lbClient *lbclient.Client
|
||||
instances cloudprovider.Instances
|
||||
instancesV2 cloudprovider.InstancesV2
|
||||
loadbalancer cloudprovider.LoadBalancer
|
||||
}
|
||||
|
||||
func newCloud(config io.Reader) (c cloudprovider.Interface, err error) {
|
||||
var opts []pve.ClientOption
|
||||
buf, _ := ioutil.ReadAll(config)
|
||||
type config struct {
|
||||
PVE pve.Config `json:"pve"`
|
||||
LB lb.Config `json:"lb"`
|
||||
}
|
||||
|
||||
func newCloud(cr io.Reader) (c cloudprovider.Interface, err error) {
|
||||
var (
|
||||
pveOpts []pve.ClientOption
|
||||
lbOpts []lb.ClientOption
|
||||
)
|
||||
buf, _ := ioutil.ReadAll(cr)
|
||||
if len(buf) != 0 {
|
||||
var cfg pve.Config
|
||||
var cfg config
|
||||
err = json.Unmarshal(buf, &cfg)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
opts, err = pve.ClientOptionsFromConfig(cfg)
|
||||
pveOpts, err = pve.ClientOptionsFromConfig(cfg.PVE)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
lbOpts, err = lb.ClientOptionsFromConfig(cfg.LB)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
opts, err = pve.ClientOptionsFromEnv()
|
||||
pveOpts, err = pve.ClientOptionsFromEnv()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
lbOpts, err = lb.ClientOptionsFromEnv()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if len(opts) == 0 {
|
||||
if len(pveOpts) == 0 {
|
||||
err = errors.New("missing pve config")
|
||||
return
|
||||
}
|
||||
if len(lbOpts) == 0 {
|
||||
err = errors.New("missing lb config")
|
||||
return
|
||||
}
|
||||
|
||||
pveClient := pve.NewClient(pveOpts...)
|
||||
lbClient, err := lbclient.NewClient(lb.NewClient(lbOpts...))
|
||||
|
||||
client := pve.NewClient(opts...)
|
||||
c = &cloud{
|
||||
client: client,
|
||||
instances: newInstances(client),
|
||||
instancesV2: newInstancesV2(client),
|
||||
pveClient: pveClient,
|
||||
lbClient: lbClient,
|
||||
instances: newInstances(pveClient),
|
||||
instancesV2: newInstancesV2(pveClient),
|
||||
loadbalancer: newLoadbalancer(lbClient),
|
||||
//zones: newZones(client, nodeName),
|
||||
//routes: nil,
|
||||
//network: network,
|
||||
|
|
@ -85,7 +113,7 @@ func (c *cloud) Zones() (cloudprovider.Zones, bool) {
|
|||
}
|
||||
|
||||
func (c *cloud) LoadBalancer() (cloudprovider.LoadBalancer, bool) {
|
||||
return nil, false
|
||||
return c.loadbalancer, true
|
||||
}
|
||||
|
||||
func (c *cloud) Clusters() (cloudprovider.Clusters, bool) {
|
||||
|
|
|
|||
119
pkg/pvecloud/loadbalancer.go
Normal file
119
pkg/pvecloud/loadbalancer.go
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package pvecloud
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
apiclient "git.giftfish.de/ston1th/haproxy-lb/pkg/api/client"
|
||||
"git.giftfish.de/ston1th/haproxy-lb/pkg/api/v1/client"
|
||||
"git.giftfish.de/ston1th/haproxy-lb/pkg/api/v1/schema"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
type loadbalancer struct {
|
||||
client *client.Client
|
||||
}
|
||||
|
||||
func newLoadbalancer(client *client.Client) *loadbalancer {
|
||||
return &loadbalancer{client}
|
||||
}
|
||||
|
||||
func name(service *v1.Service) string {
|
||||
return service.Namespace + "_" + service.Name
|
||||
}
|
||||
|
||||
func fullname(clusterName string, service *v1.Service) string {
|
||||
return clusterName + "/" + name(service)
|
||||
}
|
||||
|
||||
func lbStatus(ip string) *v1.LoadBalancerStatus {
|
||||
return &v1.LoadBalancerStatus{
|
||||
Ingress: []v1.LoadBalancerIngress{
|
||||
{IP: ip},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (lb *loadbalancer) GetLoadBalancer(ctx context.Context, clusterName string, service *v1.Service) (status *v1.LoadBalancerStatus, exists bool, err error) {
|
||||
l, err := lb.client.GetLoadBalancer(ctx, clusterName, name(service))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
exists = true
|
||||
status = lbStatus(l.IP)
|
||||
return
|
||||
}
|
||||
|
||||
func (lb *loadbalancer) GetLoadBalancerName(ctx context.Context, clusterName string, service *v1.Service) string {
|
||||
return fullname(clusterName, service)
|
||||
}
|
||||
|
||||
func (lb *loadbalancer) EnsureLoadBalancer(ctx context.Context, clusterName string, service *v1.Service, nodes []*v1.Node) (status *v1.LoadBalancerStatus, err error) {
|
||||
// TODO service annotations
|
||||
var slb schema.LoadBalancer
|
||||
for _, port := range service.Spec.Ports {
|
||||
sp := schema.Port{Port: int(port.Port)}
|
||||
for _, node := range nodes {
|
||||
if len(node.Status.Addresses) == 0 {
|
||||
continue
|
||||
}
|
||||
ip := ""
|
||||
for _, a := range node.Status.Addresses {
|
||||
if a.Type == v1.NodeInternalIP {
|
||||
ip = a.Address
|
||||
break
|
||||
} else if a.Type == v1.NodeHostName {
|
||||
ip = a.Address
|
||||
break
|
||||
} else if a.Type == v1.NodeExternalIP {
|
||||
ip = a.Address
|
||||
break
|
||||
}
|
||||
}
|
||||
if ip == "" {
|
||||
continue
|
||||
}
|
||||
sp.Servers = append(sp.Servers, schema.Server{
|
||||
Name: node.Name,
|
||||
IP: ip,
|
||||
Port: int(port.NodePort),
|
||||
})
|
||||
}
|
||||
slb.Ports = append(slb.Ports, sp)
|
||||
}
|
||||
n := name(service)
|
||||
err = lb.client.CreateLoadBalancer(ctx, clusterName, n, slb)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
l, err := lb.client.GetLoadBalancer(ctx, clusterName, n)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
status = lbStatus(l.IP)
|
||||
return
|
||||
}
|
||||
|
||||
func (lb *loadbalancer) UpdateLoadBalancer(ctx context.Context, clusterName string, service *v1.Service, nodes []*v1.Node) error {
|
||||
_, err := lb.EnsureLoadBalancer(ctx, clusterName, service, nodes)
|
||||
return err
|
||||
}
|
||||
|
||||
func (lb *loadbalancer) EnsureLoadBalancerDeleted(ctx context.Context, clusterName string, service *v1.Service) error {
|
||||
err := lb.client.DeleteLoadBalancer(ctx, clusterName, name(service))
|
||||
if err == apiclient.ErrNotFound {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue