Skip to content

Commit c4fe096

Browse files
committed
remove metallb-isms allowing the metallb plugin to work with kube-vip, metallb with crds, etc
Signed-off-by: Travis Glenn Hansen <[email protected]>
1 parent e6ff93c commit c4fe096

File tree

3 files changed

+96
-162
lines changed

3 files changed

+96
-162
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# v0.5.13
2+
3+
Released 2023-02-23
4+
5+
- remove metallb-isms allowing the `metallb` plugin to work with `kube-vip`, `metallb` with crds, etc
6+
17
# v0.5.12
28

39
Released 2023-02-04

README.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ combination of Layer2 or BGP type configurations. Layer2 requires no integratio
6060
leverage the BGP implementation you need a BGP server along with neighbor configuration. `kpc` *dynamically* updates
6161
bgp neighbors for you in pfSense by continually monitoring cluster `Node`s.
6262

63+
While this plugin is *named* `metallb` it does not **require** MetalLB to be installed or in use. It can be used with
64+
`kube-vip` or any other service that requires BGP peers/neighbors.
65+
6366
The plugin assumes you've already installed openbgp or frr and configured it as well as created a `group` to use with
6467
MetalLB.
6568

@@ -68,11 +71,14 @@ MetalLB.
6871
enabled: true
6972
nodeLabelSelector:
7073
nodeFieldSelector:
71-
#configMap: "metallb-system/config"
7274
# pick 1 implementation
73-
bgp-implementation: openbgp
74-
# bgp-implementation: frr
75+
# bgp-implementation: openbgp
76+
bgp-implementation: frr
7577
options:
78+
frr:
79+
template:
80+
peergroup: metallb
81+
7682
openbgp:
7783
template:
7884
md5sigkey:
@@ -81,9 +87,6 @@ MetalLB.
8187
row:
8288
- parameters: announce all
8389
parmvalue:
84-
frr:
85-
template:
86-
peergroup: metallb
8790
```
8891
8992
## haproxy-declarative

src/KubernetesPfSenseController/Plugin/MetalLB.php

Lines changed: 81 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,6 @@ public function init()
2727
$pluginConfig = $this->getConfig();
2828
$nodeLabelSelector = $pluginConfig['nodeLabelSelector'] ?? null;
2929
$nodeFieldSelector = $pluginConfig['nodeFieldSelector'] ?? null;
30-
$configMap = $pluginConfig['configMap'] ?? "metallb-system/config";
31-
$configMapNamespace = explode("/", $configMap)[0];
32-
$configMapName = explode("/", $configMap)[1];
33-
34-
// metallb config
35-
$watch = $controller->getKubernetesClient()->createWatch("/api/v1/watch/namespaces/{$configMapNamespace}/configmaps/{$configMapName}", [], $this->getMetalLbConfigWatchCallback());
36-
$this->addWatch($watch);
3730

3831
// initial load of nodes
3932
$params = [
@@ -54,28 +47,6 @@ public function init()
5447
$this->delayedAction();
5548
}
5649

57-
/**
58-
* Callback for the metallb configmqp
59-
*
60-
* @return \Closure
61-
*/
62-
private function getMetalLbConfigWatchCallback()
63-
{
64-
return function ($event, $watch) {
65-
$this->logEvent($event);
66-
switch ($event['type']) {
67-
case 'ADDED':
68-
case 'MODIFIED':
69-
$this->state['metallb-config'] = yaml_parse($event['object']['data']['config']);
70-
$this->delayedAction();
71-
break;
72-
case 'DELETED':
73-
$this->state['metallb-config'] = null;
74-
break;
75-
}
76-
};
77-
}
78-
7950
/**
8051
* Deinit the plugin
8152
*/
@@ -104,13 +75,8 @@ public function postReadWatches()
10475
*/
10576
public function doAction()
10677
{
107-
$metalConfig = $this->state['metallb-config'] ?? [];
10878
$pluginConfig = $this->getConfig();
10979

110-
if (empty($metalConfig)) {
111-
return false;
112-
}
113-
11480
switch ($pluginConfig['bgp-implementation']) {
11581
case 'openbgp':
11682
case 'frr':
@@ -130,7 +96,6 @@ public function doAction()
13096
*/
13197
private function doActionGeneric()
13298
{
133-
$metalConfig = $this->state['metallb-config'];
13499
$pluginConfig = $this->getConfig();
135100

136101
switch ($pluginConfig['bgp-implementation']) {
@@ -154,146 +119,106 @@ private function doActionGeneric()
154119
$bgpConfig->data['config'] = [];
155120
}
156121

157-
$bgpEnabled = false;
158-
foreach ($metalConfig['address-pools'] as $pool) {
159-
if ($pool['protocol'] == 'bgp') {
160-
$bgpEnabled = true;
122+
// add/remove as necessary
123+
$template = $pluginConfig['options'][$pluginConfig['bgp-implementation']]['template'];
124+
switch ($pluginConfig['bgp-implementation']) {
125+
case 'openbgp':
126+
$defaults = [
127+
'md5sigkey' => (string) $template['md5sigkey'],
128+
'md5sigpass' => (string) $template['md5sigpass'],
129+
'groupname' => (string) $template['groupname'],
130+
];
131+
$template = array_merge($defaults, $template);
132+
$template = array_map(function ($v) {
133+
return $v ?: '';
134+
}, $template);
135+
break;
136+
case 'frr':
137+
$defaults = [
138+
"sendcommunity" => "disabled",
139+
];
140+
$template = array_merge($defaults, $template);
141+
$template = array_map(function ($v) {
142+
return $v ?: '';
143+
}, $template);
161144
break;
162-
}
163145
}
164146

165-
if ($bgpEnabled) {
166-
// add/remove as necessary
167-
$template = $pluginConfig['options'][$pluginConfig['bgp-implementation']]['template'];
147+
$nodes = $this->state['nodes'];
148+
$neighbors = [];
149+
$managedNeighborsPreSave = [];
150+
foreach ($nodes as $node) {
151+
$host = 'kpc-'.KubernetesUtils::getNodeIp($node);
152+
$managedNeighborsPreSave[$host] = [
153+
'resource' => $this->getKubernetesResourceDetails($node),
154+
];
155+
$neighbor = $template;
156+
168157
switch ($pluginConfig['bgp-implementation']) {
169158
case 'openbgp':
170-
$defaults = [
171-
'md5sigkey' => (string) $template['md5sigkey'],
172-
'md5sigpass' => (string) $template['md5sigpass'],
173-
'groupname' => (string) $template['groupname'],
174-
];
175-
$template = array_merge($defaults, $template);
176-
$template = array_map(function ($v) {
177-
return $v ?: '';
178-
}, $template);
159+
$neighbor['descr'] = $host;
160+
$neighbor['neighbor'] = KubernetesUtils::getNodeIp($node);
179161
break;
180162
case 'frr':
181-
$defaults = [
182-
"sendcommunity" => "disabled",
183-
];
184-
$template = array_merge($defaults, $template);
185-
$template = array_map(function ($v) {
186-
return $v ?: '';
187-
}, $template);
163+
$neighbor['descr'] = $host;
164+
$neighbor['peer'] = KubernetesUtils::getNodeIp($node);
188165
break;
189166
}
190167

191-
$nodes = $this->state['nodes'];
192-
$neighbors = [];
193-
$managedNeighborsPreSave = [];
194-
foreach ($nodes as $node) {
195-
$host = 'kpc-'.KubernetesUtils::getNodeIp($node);
196-
$managedNeighborsPreSave[$host] = [
197-
'resource' => $this->getKubernetesResourceDetails($node),
198-
];
199-
$neighbor = $template;
200-
201-
switch ($pluginConfig['bgp-implementation']) {
202-
case 'openbgp':
203-
$neighbor['descr'] = $host;
204-
$neighbor['neighbor'] = KubernetesUtils::getNodeIp($node);
205-
break;
206-
case 'frr':
207-
$neighbor['descr'] = $host;
208-
$neighbor['peer'] = KubernetesUtils::getNodeIp($node);
209-
break;
210-
}
211-
212-
$neighbors[] = $neighbor;
213-
}
214-
215-
// get store data
216-
$store = $this->getStore();
217-
if (empty($store)) {
218-
$store = [];
219-
}
220-
221-
$store[$pluginConfig['bgp-implementation']] = $store[$pluginConfig['bgp-implementation']] ?? [];
222-
$store[$pluginConfig['bgp-implementation']]['managed_neighbors'] = $store[$pluginConfig['bgp-implementation']]['managed_neighbors'] ?? [];
168+
$neighbors[] = $neighbor;
169+
}
223170

224-
$managedNeighborNamesPreSave = @array_keys($managedNeighborsPreSave);
225-
$managedNeighborNames = @array_keys($store[$pluginConfig['bgp-implementation']]['managed_neighbors']);
226-
if (empty($managedNeighborNames)) {
227-
$managedNeighborNames = [];
228-
}
171+
// get store data
172+
$store = $this->getStore();
173+
if (empty($store)) {
174+
$store = [];
175+
}
229176

230-
// update config with new/updated items
231-
foreach ($neighbors as $neighbor) {
232-
Utils::putListItem($bgpConfig->data['config'], $neighbor, 'descr');
233-
}
177+
$store[$pluginConfig['bgp-implementation']] = $store[$pluginConfig['bgp-implementation']] ?? [];
178+
$store[$pluginConfig['bgp-implementation']]['managed_neighbors'] = $store[$pluginConfig['bgp-implementation']]['managed_neighbors'] ?? [];
234179

235-
// remove items from config
236-
$toDeleteItemNames = array_diff($managedNeighborNames, $managedNeighborNamesPreSave);
237-
foreach ($toDeleteItemNames as $itemId) {
238-
Utils::removeListItem($bgpConfig->data['config'], $itemId, 'descr');
239-
}
180+
$managedNeighborNamesPreSave = @array_keys($managedNeighborsPreSave);
181+
$managedNeighborNames = @array_keys($store[$pluginConfig['bgp-implementation']]['managed_neighbors']);
182+
if (empty($managedNeighborNames)) {
183+
$managedNeighborNames = [];
184+
}
240185

241-
// prep config for save
242-
if (empty($bgpConfig->data['config'])) {
243-
$bgpConfig->data = null;
244-
}
186+
// update config with new/updated items
187+
foreach ($neighbors as $neighbor) {
188+
$this->log('ensuring peer: '.$neighbor['descr']);
189+
Utils::putListItem($bgpConfig->data['config'], $neighbor, 'descr');
190+
}
245191

246-
// save newly managed configuration
247-
try {
248-
$this->savePfSenseConfigBlock($bgpConfig);
249-
switch ($pluginConfig['bgp-implementation']) {
250-
case 'openbgp':
251-
$this->reloadOpenbgp();
252-
break;
253-
case 'frr':
254-
$this->reloadFrrBgp();
255-
break;
256-
}
257-
$store[$pluginConfig['bgp-implementation']]['managed_neighbors'] = $managedNeighborsPreSave;
258-
$this->saveStore($store);
192+
// remove items from config
193+
$toDeleteItemNames = array_diff($managedNeighborNames, $managedNeighborNamesPreSave);
194+
foreach ($toDeleteItemNames as $itemId) {
195+
$this->log('removing peer: '.$itemId);
196+
Utils::removeListItem($bgpConfig->data['config'], $itemId, 'descr');
197+
}
259198

260-
return true;
261-
} catch (\Exception $e) {
262-
$this->log('failed update/reload: '.$e->getMessage().' ('.$e->getCode().')');
263-
return false;
264-
}
265-
} else {
266-
//remove any nodes from config
267-
// get storage data
268-
$store = $this->getStore();
269-
$managedNeighborNames = @array_keys($store[$pluginConfig['bgp-implementation']]['managed_neighbors']);
270-
if (empty($managedNeighborNames)) {
271-
return true;
272-
}
199+
// prep config for save
200+
if (empty($bgpConfig->data['config'])) {
201+
$bgpConfig->data = null;
202+
}
273203

274-
foreach ($managedNeighborNames as $itemId) {
275-
Utils::removeListItem($bgpConfig->data['config'], $itemId, 'descr');
204+
// save newly managed configuration
205+
try {
206+
$this->savePfSenseConfigBlock($bgpConfig);
207+
switch ($pluginConfig['bgp-implementation']) {
208+
case 'openbgp':
209+
$this->reloadOpenbgp();
210+
break;
211+
case 'frr':
212+
$this->reloadFrrBgp();
213+
break;
276214
}
215+
$store[$pluginConfig['bgp-implementation']]['managed_neighbors'] = $managedNeighborsPreSave;
216+
$this->saveStore($store);
277217

278-
// save newly managed configuration
279-
try {
280-
$this->savePfSenseConfigBlock($bgpConfig);
281-
switch ($pluginConfig['bgp-implementation']) {
282-
case 'openbgp':
283-
$this->reloadOpenbgp();
284-
break;
285-
case 'frr':
286-
$this->reloadFrrBgp();
287-
break;
288-
}
289-
$store[$pluginConfig['bgp-implementation']]['managed_neighbors'] = [];
290-
$this->saveStore($store);
291-
292-
return true;
293-
} catch (\Exception $e) {
294-
$this->log('failed update/reload: '.$e->getMessage().' ('.$e->getCode().')');
295-
return false;
296-
}
218+
return true;
219+
} catch (\Exception $e) {
220+
$this->log('failed update/reload: '.$e->getMessage().' ('.$e->getCode().')');
221+
return false;
297222
}
298223
}
299224
}

0 commit comments

Comments
 (0)