-
Notifications
You must be signed in to change notification settings - Fork 2.7k
/
metallb.go
108 lines (96 loc) · 3.33 KB
/
metallb.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium
package speaker
import (
"context"
"fmt"
"os"
"go.universe.tf/metallb/pkg/config"
"go.universe.tf/metallb/pkg/k8s/types"
metallbspr "go.universe.tf/metallb/pkg/speaker"
bgpconfig "github.com/cilium/cilium/pkg/bgp/config"
bgpk8s "github.com/cilium/cilium/pkg/bgp/k8s"
bgplog "github.com/cilium/cilium/pkg/bgp/log"
"github.com/cilium/cilium/pkg/k8s/client"
nodetypes "github.com/cilium/cilium/pkg/node/types"
"github.com/cilium/cilium/pkg/option"
)
// Speaker provides a method set for interfacing
// with a BGP speaker.
//
// This interface is heavily modeled after MetalLB's speaker
// as it's the first BGP integration for Cilium's use cases.
//
// If other BGP integrations are desired, consider building out custom types
// and a more abstracted method set.
type Speaker interface {
// SetService will announce the provided Service of type LoadBalancer to BGP peers.
SetService(name string, svc *metallbspr.Service, eps *metallbspr.Endpoints) types.SyncState
// SetNodeLabels will create or delete any BGP sessions given the provided labels
// allow for this.
//
// The provided labels will be used to determine if the Speaker allows for BGP
// peering.
SetNodeLabels(labels map[string]string) types.SyncState
// PeerSessions returns any active BGP sessions.
PeerSessions() []metallbspr.Session
// GetBGPController returns the BGPController of the speaker
GetBGPController() *metallbspr.BGPController
}
// metalLBSpeaker implements the Speaker interface
// and is thin wrapper around the metallb controller proper.
type metalLBSpeaker struct {
C *metallbspr.Controller
logger *bgplog.Logger
}
// newMetalLBSpeaker will create a new Speaker powered by
// a MetalLB BGP Speaker.
//
// This constructor expects option.Config.BGPConfigPath to point to
// a valid filesystem path where a MetalLB configure resides.
// It's an error if the config cannot be parsed.
//
// The MetalLB speaker will use the value of nodetypes.GetName() as
// its node identity.
func newMetalLBSpeaker(ctx context.Context, clientset client.Clientset) (Speaker, error) {
logger := &bgplog.Logger{Entry: log}
client := bgpk8s.New(logger.Logger, clientset)
c, err := metallbspr.NewController(metallbspr.ControllerConfig{
MyNode: nodetypes.GetName(),
Logger: logger,
SList: nil, // BGP speaker doesn't use speakerlist
DisableLayer2: true,
})
if err != nil {
return nil, err
}
c.Client = client
f, err := os.Open(option.Config.BGPConfigPath)
if err != nil {
return nil, err
}
defer f.Close()
config, err := bgpconfig.Parse(f)
if err != nil {
return nil, err
}
if ss := c.SetConfig(logger, config); ss == types.SyncStateError {
return nil, fmt.Errorf("failed to set MetalLB config")
}
return metalLBSpeaker{
C: c,
logger: logger,
}, nil
}
func (m metalLBSpeaker) SetService(name string, svc *metallbspr.Service, eps *metallbspr.Endpoints) types.SyncState {
return m.C.SetService(m.logger, name, svc, eps)
}
func (m metalLBSpeaker) SetNodeLabels(labels map[string]string) types.SyncState {
return m.C.SetNodeLabels(m.logger, labels)
}
func (m metalLBSpeaker) PeerSessions() []metallbspr.Session {
return m.C.PeerSessions()
}
func (m metalLBSpeaker) GetBGPController() *metallbspr.BGPController {
return m.C.Protocols[config.BGP].(*metallbspr.BGPController)
}