Skip to content

Commit e3e5a60

Browse files
authored
Merge pull request #168 from projectsyn/feat/enterprise-bgp-control-plane
Add support for configuring Enterprise BGP control plane
2 parents 2b7101a + 7fba3e5 commit e3e5a60

31 files changed

+1306
-29
lines changed

.cruft.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"template": "https://github.com/projectsyn/commodore-component-template.git",
3-
"commit": "98d16f99766e6c6d97322dbe42e058f0e2bf73d0",
3+
"commit": "56dd2ee980f197ec2c8b3977c16458e43d0c6ef2",
44
"checkout": "main",
55
"context": {
66
"cookiecutter": {
77
"name": "Cilium",
88
"slug": "cilium",
99
"parameter_key": "cilium",
10-
"test_cases": "defaults helm-opensource olm-opensource egress-gateway bgp-control-plane kubeproxyreplacement-strict l2-announcement clustermesh",
10+
"test_cases": "defaults helm-opensource olm-opensource egress-gateway bgp-control-plane kubeproxyreplacement-strict l2-announcement clustermesh enterprise-bgp",
1111
"add_lib": "n",
1212
"add_pp": "n",
1313
"add_golden": "y",
@@ -25,7 +25,7 @@
2525
"github_name": "component-cilium",
2626
"github_url": "https://github.com/projectsyn/component-cilium",
2727
"_template": "https://github.com/projectsyn/commodore-component-template.git",
28-
"_commit": "98d16f99766e6c6d97322dbe42e058f0e2bf73d0"
28+
"_commit": "56dd2ee980f197ec2c8b3977c16458e43d0c6ef2"
2929
}
3030
},
3131
"directory": null

.github/workflows/test.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ jobs:
4040
- kubeproxyreplacement-strict
4141
- l2-announcement
4242
- clustermesh
43+
- enterprise-bgp
4344
defaults:
4445
run:
4546
working-directory: ${{ env.COMPONENT_NAME }}
@@ -62,6 +63,7 @@ jobs:
6263
- kubeproxyreplacement-strict
6364
- l2-announcement
6465
- clustermesh
66+
- enterprise-bgp
6567
defaults:
6668
run:
6769
working-directory: ${{ env.COMPONENT_NAME }}

Makefile.vars.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,4 @@ KUBENT_IMAGE ?= ghcr.io/doitintl/kube-no-trouble:latest
5757
KUBENT_DOCKER ?= $(DOCKER_CMD) $(DOCKER_ARGS) $(root_volume) --entrypoint=/app/kubent $(KUBENT_IMAGE)
5858

5959
instance ?= defaults
60-
test_instances = tests/defaults.yml tests/helm-opensource.yml tests/olm-opensource.yml tests/egress-gateway.yml tests/bgp-control-plane.yml tests/kubeproxyreplacement-strict.yml tests/l2-announcement.yml tests/clustermesh.yml
60+
test_instances = tests/defaults.yml tests/helm-opensource.yml tests/olm-opensource.yml tests/egress-gateway.yml tests/bgp-control-plane.yml tests/kubeproxyreplacement-strict.yml tests/l2-announcement.yml tests/clustermesh.yml tests/enterprise-bgp.yml

class/defaults.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ parameters:
105105

106106
bgp:
107107
enabled: false
108+
enterprise: false
108109
cluster_configs: {}
109110
peer_configs: {}
110111
auth_secrets: {}

component/bgp-control-plane.jsonnet

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,18 @@ local util = import 'util.libsonnet';
77
local inv = kap.inventory();
88
local params = inv.parameters.cilium;
99

10+
local crd_prefix = if params.bgp.enterprise then 'Isovalent' else 'Cilium';
11+
local apiVersion = if params.bgp.enterprise then (
12+
if util.version.minor >= 17 then
13+
'isovalent.com/v1'
14+
else
15+
'isovalent.com/v1alpha1'
16+
)
17+
else
18+
'cilium.io/v2alpha1';
19+
1020
local CiliumBGPClusterConfig(name) =
11-
kube._Object('cilium.io/v2alpha1', 'CiliumBGPClusterConfig', name) {
21+
kube._Object(apiVersion, '%sBGPClusterConfig' % crd_prefix, name) {
1222
metadata+: {
1323
annotations+: {
1424
'argocd.argoproj.io/sync-options': 'SkipDryRunOnMissingResource=true',
@@ -18,7 +28,7 @@ local CiliumBGPClusterConfig(name) =
1828
};
1929

2030
local CiliumBGPPeerConfig(name) =
21-
kube._Object('cilium.io/v2alpha1', 'CiliumBGPPeerConfig', name) {
31+
kube._Object(apiVersion, '%sBGPPeerConfig' % crd_prefix, name) {
2232
metadata+: {
2333
annotations+: {
2434
'argocd.argoproj.io/sync-options': 'SkipDryRunOnMissingResource=true',
@@ -28,7 +38,7 @@ local CiliumBGPPeerConfig(name) =
2838
};
2939

3040
local CiliumBGPAdvertisement(name) =
31-
kube._Object('cilium.io/v2alpha1', 'CiliumBGPAdvertisement', name) {
41+
kube._Object(apiVersion, '%sBGPAdvertisement' % crd_prefix, name) {
3242
metadata+: {
3343
annotations+: {
3444
'argocd.argoproj.io/sync-options': 'SkipDryRunOnMissingResource=true',
@@ -38,7 +48,7 @@ local CiliumBGPAdvertisement(name) =
3848
};
3949

4050
local CiliumBGPNodeConfigOverride(name) =
41-
kube._Object('cilium.io/v2alpha1', 'CiliumBGPNodeConfigOverride', name) {
51+
kube._Object(apiVersion, '%sBGPNodeConfigOverride' % crd_prefix, name) {
4252
metadata+: {
4353
annotations+: {
4454
'argocd.argoproj.io/sync-options': 'SkipDryRunOnMissingResource=true',
@@ -72,8 +82,8 @@ local render_peer_config(name, config) =
7282
local secretname = std.get(pconfig.spec, 'authSecretRef');
7383
assert
7484
secretname == null || std.member(auth_secret_names, secretname)
75-
: "CiliumBGPPeerConfig `%s` references auth secret `%s` which doesn't exist"
76-
% [ name, secretname ];
85+
: "%sBGPPeerConfig `%s` references auth secret `%s` which doesn't exist"
86+
% [ crd_prefix, name, secretname ];
7787
pconfig;
7888
validate_peer_config({
7989
metadata+: std.get(config, 'metadata', {}),
@@ -94,10 +104,10 @@ local render_cluster_config(name, config) =
94104
local pcfgname = std.get(pconfig, 'peerConfigRef', { name: '' }).name;
95105
assert
96106
std.member(peerConfigNames, pcfgname)
97-
: 'Peer `%s` in BGP instance `%s` in CiliumBGPClusterConfig `%s` ' %
98-
[ pconfig.name, iname, name ]
99-
+ "references CiliumBGPPeerConfig `%s` which doesn't exist" %
100-
[ pcfgname ];
107+
: 'Peer `%s` in BGP instance `%s` in %sBGPClusterConfig `%s` ' %
108+
[ pconfig.name, iname, crd_prefix, name ]
109+
+ "references %sBGPPeerConfig `%s` which doesn't exist" %
110+
[ crd_prefix, pcfgname ];
101111
pconfig;
102112
local render_instance(name, iconfig) =
103113
local cfg = iconfig {

component/olm.jsonnet

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,22 @@ local params = inv.parameters.cilium;
88
local helm = import 'render-helm-values.jsonnet';
99
local util = import 'util.libsonnet';
1010

11+
// NOTE(sg): We introduce hidden parameter `__mock_enterprise` which can be
12+
// set to `true` in test cases to test `params.release == enterprise` behavior
13+
// while downloading the opensource OLM tarball (see test case
14+
// `enterprise-bgp` for an example).
15+
// Notably, we must override this for most of the OLM processing, since we're
16+
// using the opensource OLM manifests for the mock enterprise test.
17+
local release = if std.get(params, '__mock_enterprise', false) then
18+
'opensource'
19+
else
20+
params.release;
21+
1122
local olmDir =
1223
local prefix = '%s/olm/cilium/cilium-olm/' % inv.parameters._base_directory;
13-
if params.release == 'opensource' then
24+
if release == 'opensource' then
1425
prefix + 'olm-for-cilium-main/manifests/cilium.v%s/' % params.olm.full_version
15-
else if params.release == 'enterprise' then
26+
else if release == 'enterprise' then
1627
local path_variants = [
1728
// Known releases: 1.11.5, 1.12.6
1829
'',
@@ -39,7 +50,7 @@ local olmDir =
3950
else
4051
dir
4152
else
42-
error "Unknown release '%s'" % [ params.release ];
53+
error "Unknown release '%s'" % [ release ];
4354

4455
local olmFiles = std.foldl(
4556
function(status, file)
@@ -98,7 +109,7 @@ local patchManifests = function(file, has_csv)
98109
'--zap-log-level=%s' % params.olm.log_level,
99110
],
100111
env+:
101-
if params.release == 'opensource' then
112+
if release == 'opensource' then
102113
(
103114
if hasK8sHost then
104115
[
@@ -143,13 +154,16 @@ local patchManifests = function(file, has_csv)
143154
},
144155
} else {},
145156
};
157+
// NOTE(sg): This is explicitly `params.relase` since we don't want the
158+
// fall back to the opensource logic for the __mock_enterprise=true test
159+
// cases.
146160
if params.release == 'enterprise' then {
147161
cilium+: patch,
148162
} else
149163
patch;
150164
if (
151165
file.contents.kind == 'CiliumConfig'
152-
&& file.contents.metadata.name == metadata_name_map[params.release].CiliumConfig
166+
&& file.contents.metadata.name == metadata_name_map[release].CiliumConfig
153167
&& file.contents.metadata.namespace == 'cilium'
154168
) then
155169
file {
@@ -158,7 +172,7 @@ local patchManifests = function(file, has_csv)
158172
},
159173
}
160174
else if (
161-
params.release == 'enterprise'
175+
release == 'enterprise'
162176
&& file.contents.kind == 'ConfigMap'
163177
&& file.contents.metadata.name == 'cilium-ee-olm-overrides'
164178
&& file.contents.metadata.namespace == 'cilium'
@@ -175,7 +189,7 @@ local patchManifests = function(file, has_csv)
175189
}
176190
else if (
177191
file.contents.kind == 'Deployment'
178-
&& file.contents.metadata.name == metadata_name_map[params.release].Deployment
192+
&& file.contents.metadata.name == metadata_name_map[release].Deployment
179193
&& file.contents.metadata.namespace == 'cilium'
180194
) then
181195
file {
@@ -191,7 +205,7 @@ local patchManifests = function(file, has_csv)
191205
install+: {
192206
spec+: {
193207
deployments: [
194-
if d.name == metadata_name_map[params.release].Deployment then
208+
if d.name == metadata_name_map[release].Deployment then
195209
d + deploymentPatch
196210
else
197211
d
@@ -216,7 +230,7 @@ local patchManifests = function(file, has_csv)
216230
else if (
217231
file.contents.kind == 'Role' &&
218232
file.contents.metadata.namespace == 'cilium' &&
219-
file.contents.metadata.name == metadata_name_map[params.release].OlmRole
233+
file.contents.metadata.name == metadata_name_map[release].OlmRole
220234
) then
221235
file {
222236
contents+: {
@@ -255,7 +269,7 @@ local patchManifests = function(file, has_csv)
255269
}
256270
else if (
257271
file.contents.kind == 'ClusterRole' &&
258-
file.contents.metadata.name == metadata_name_map[params.release].OlmClusterRole
272+
file.contents.metadata.name == metadata_name_map[release].OlmClusterRole
259273
) then
260274
file {
261275
contents+: {
@@ -304,7 +318,7 @@ local patchManifests = function(file, has_csv)
304318
file;
305319

306320
local kubeSystemSecretRO = [
307-
kube.Role(metadata_name_map[params.release].OlmRole) {
321+
kube.Role(metadata_name_map[release].OlmRole) {
308322
metadata+: {
309323
namespace: 'kube-system',
310324
},
@@ -316,20 +330,20 @@ local kubeSystemSecretRO = [
316330
},
317331
],
318332
},
319-
kube.RoleBinding(metadata_name_map[params.release].OlmRole) {
333+
kube.RoleBinding(metadata_name_map[release].OlmRole) {
320334
metadata+: {
321335
namespace: 'kube-system',
322336
},
323337
roleRef: {
324338
apiGroup: 'rbac.authorization.k8s.io',
325339
kind: 'Role',
326-
name: metadata_name_map[params.release].OlmRole,
340+
name: metadata_name_map[release].OlmRole,
327341
},
328342
subjects: [
329343
{
330344
kind: 'ServiceAccount',
331345
namespace: 'cilium',
332-
name: metadata_name_map[params.release].OlmRole,
346+
name: metadata_name_map[release].OlmRole,
333347
},
334348
],
335349
},

component/render-helm-values.jsonnet

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,33 @@ local forceBPFMasqueradeEgressGW = {
5959
},
6060
};
6161

62+
local enterpriseBGPControlPlane =
63+
if params.release != 'enterprise' then
64+
std.trace('Cannot enable enterprise BGP control plane on opensource Cilium', {})
65+
else if params.bgp.enterprise then
66+
std.trace(
67+
'User requested Enterprise BGP control plane: ' +
68+
'Moving `bgpControlPlane` Helm values to `enterprise.bgpControlPlane` ' +
69+
'and generating `IsovalentBGP*` resources.',
70+
{
71+
local bgp_values = super.bgpControlPlane,
72+
bgpControlPlane: {
73+
enabled: false,
74+
},
75+
enterprise+: {
76+
bgpControlPlane+: bgp_values,
77+
},
78+
}
79+
)
80+
else
81+
{};
82+
6283
local cilium_values = std.prune(
6384
params.cilium_helm_values +
6485
replaceDeprecatedIPv4PodCIDR +
6586
renderPodCIDRList +
66-
forceBPFMasqueradeEgressGW
87+
forceBPFMasqueradeEgressGW +
88+
enterpriseBGPControlPlane
6789
);
6890

6991
local helm_values = {

docs/modules/ROOT/pages/references/parameters.adoc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,28 @@ Whether to enable the BGP control plane feature in Cilium.
691691

692692
See the https://docs.cilium.io/en/{helm-minor-version}/network/bgp-control-plane/bgp-control-plane-v2/[upstream BGP control plane documentation] for details on the architecture and the individual custom resources mentioned in this section.
693693

694+
=== `bgp.enterprise`
695+
696+
[horizontal]
697+
type:: bool
698+
default:: `false`
699+
700+
Whether to enable the enterprise BGP control plane feature in Cilium.
701+
This parameter has no effect if the component is used to deploy non-enterprise Cilium.
702+
703+
When this parameter is set to `true`, the component will copy the contents of Helm value `bgpControlPlane` to Helm value `enterprise.bgpControlPlane`.
704+
Additionally, the component will override Helm value `bgpControlPlane.enabled` to `false`, since Cilium doesn't support having both control planes enabled simultaneously.
705+
This mechanism allows users to switch between the non-enterprise and enterprise BGP control plane without having to manually move Helm values.
706+
707+
See the https://docs.isovalent.com/configuration-guide/networking/bgp/index.html[Enterprise documentation] for details on the enterprise BGP control plane.
708+
709+
[NOTE]
710+
====
711+
The component will automatically deploy `IsovalentBGP*` resources instead of `CiliumBGP*` resources for the following parameters when the enterprise control plane is enabled.
712+
713+
The `IsovalentBGP*` resources are structurally equivalent to the `CiliumBGP*` resources, but support the additional enterprise features, such as egress IP announcements.
714+
====
715+
694716
=== `bgp.cluster_configs`
695717

696718
[horizontal]

tests/enterprise-bgp.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
parameters:
2+
kapitan:
3+
dependencies:
4+
- type: https
5+
source: https://raw.githubusercontent.com/appuio/component-openshift4-monitoring/v6.11.3/lib/openshift4-monitoring-prom.libsonnet
6+
output_path: vendor/lib/prom.libsonnet
7+
- type: https
8+
source: https://raw.githubusercontent.com/appuio/component-openshift4-monitoring/v6.11.3/lib/openshift4-monitoring-alert-patching.libsonnet
9+
output_path: vendor/lib/alert-patching.libsonnet
10+
11+
cilium:
12+
install_method: olm
13+
release: enterprise
14+
__mock_enterprise: true
15+
olm:
16+
source:
17+
enterprise: https://github.com/isovalent/olm-for-cilium/archive/main.tar.gz
18+
19+
bgp:
20+
enabled: true
21+
enterprise: true
22+
cluster_configs:
23+
lb-services:
24+
nodeSelector:
25+
matchLabels:
26+
node-role.kubernetes.io/infra: ''
27+
bgpInstances:
28+
lbs:
29+
localASN: 64512
30+
peers:
31+
peer1:
32+
peerAddress: 192.0.2.2
33+
peerASN: 64512
34+
peerConfigRef:
35+
name: lb-services
36+
peer2:
37+
peerAddress: 192.0.2.3
38+
peerASN: 64512
39+
peerConfigRef:
40+
name: lb-services
41+
peer_configs:
42+
lb-services:
43+
spec:
44+
gracefulRestart:
45+
enabled: true
46+
restartTimeSeconds: 30
47+
families:
48+
unicast-v4:
49+
afi: ipv4
50+
safi: unicast
51+
advertisements:
52+
matchLabels:
53+
cilium.syn.tools/advertise: bgp

tests/golden/enterprise-bgp/cilium/apps/cilium.yaml

Whitespace-only changes.

0 commit comments

Comments
 (0)