Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add calico bgp
Browse files Browse the repository at this point in the history
defo89 committed Oct 8, 2024
1 parent 52f0a24 commit 7fd1f02
Showing 14 changed files with 659 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
apiVersion: v1
description: Helm chart for Calico BGP
name: calico-bgp
version: 0.1.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: crd.projectcalico.org/v1
kind: BGPConfiguration
metadata:
name: default
spec:
logSeverityScreen: {{ .Values.bgp.logSeverityScreen }}
nodeToNodeMeshEnabled: {{ .Values.bgp.nodeToNodeMeshEnabled }}
asNumber: {{ required ".Values.bgp.asNumber is required" .Values.bgp.asNumber }}
{{- if .Values.bgp.serviceLoadBalancerIPs }}
serviceLoadBalancerIPs:
{{- range $cidr := .Values.bgp.serviceLoadBalancerIPs }}
- cidr: {{ $cidr }}
{{- end }}
{{- end }}
{{- if .Values.bgp.serviceExternalIPs }}
serviceExternalIPs:
{{- range $cidr := .Values.bgp.serviceExternalIPs }}
- cidr: {{ $cidr }}
{{- end }}
{{- end }}
{{- if .Values.bgp.serviceClusterIPs }}
serviceClusterIPs:
{{- range $cidr := .Values.bgp.serviceClusterIPs }}
- cidr: {{ $cidr }}
{{- end }}
{{- end }}
listenPort: {{ .Values.bgp.listenPort }}
bindMode: {{ .Values.bgp.bindMode }}

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{{- if .Values.bgp.bgpPeer }}
{{- range $peer := .Values.bgp.bgpPeer }}
apiVersion: crd.projectcalico.org/v1
kind: BGPPeer
metadata:
name: bgppeer-{{ $peer.peerIP }}-{{ $peer.asNumber }}
spec:
asNumber: {{ required ".peer.asNumber is required" $peer.asNumber }}
{{- if $peer.nodeSelector }}
nodeSelector: {{ $peer.nodeSelector }}
{{- end }}
peerIP: {{ required ".peer.peerIP is required" $peer.peerIP }}
{{- end }}
{{- end }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
bgp:
logSeverityScreen: Info
nodeToNodeMeshEnabled: false
listenPort: 179
bindMode: NodeIP
3 changes: 3 additions & 0 deletions charts/internal/shoot-system-components/values.yaml
Original file line number Diff line number Diff line change
@@ -3,3 +3,6 @@ cloud-controller-manager:

metallb:
enabled: false

calico-bgp:
enabled: false
147 changes: 147 additions & 0 deletions hack/api-reference/api.md
Original file line number Diff line number Diff line change
@@ -180,6 +180,139 @@ string
</tr>
</tbody>
</table>
<h3 id="metal.provider.extensions.gardener.cloud/v1alpha1.BgpPeer">BgpPeer
</h3>
<p>
(<em>Appears on:</em>
<a href="#metal.provider.extensions.gardener.cloud/v1alpha1.CalicoBgpConfig">CalicoBgpConfig</a>)
</p>
<p>
<p>BgpPeer contains configuration for BGPPeer resource.</p>
</p>
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>peerIP</code></br>
<em>
string
</em>
</td>
<td>
<p>PeerIP contains IP address of BGP peer followed by an optional port number to peer with.</p>
</td>
</tr>
<tr>
<td>
<code>asNumber</code></br>
<em>
int
</em>
</td>
<td>
<p>ASNumber contains the AS number of the BGP peer.</p>
</td>
</tr>
<tr>
<td>
<code>nodeSelector</code></br>
<em>
string
</em>
</td>
<td>
<em>(Optional)</em>
<p>NodeSelector is a key-value pair to select nodes that should have this peering.</p>
</td>
</tr>
</tbody>
</table>
<h3 id="metal.provider.extensions.gardener.cloud/v1alpha1.CalicoBgpConfig">CalicoBgpConfig
</h3>
<p>
(<em>Appears on:</em>
<a href="#metal.provider.extensions.gardener.cloud/v1alpha1.LoadBalancerConfig">LoadBalancerConfig</a>)
</p>
<p>
<p>CalicoBgpConfig contains BGP configuration settings for calico.</p>
</p>
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>asNumber</code></br>
<em>
int
</em>
</td>
<td>
<p>ASNumber is the default AS number used by a node.</p>
</td>
</tr>
<tr>
<td>
<code>serviceLoadBalancerIPs</code></br>
<em>
[]string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ServiceLoadBalancerIPs are the CIDR blocks for Kubernetes Service LoadBalancer IPs.</p>
</td>
</tr>
<tr>
<td>
<code>serviceExternalIPs</code></br>
<em>
[]string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ServiceExternalIPs are the CIDR blocks for Kubernetes Service External IPs.</p>
</td>
</tr>
<tr>
<td>
<code>serviceClusterIPs</code></br>
<em>
[]string
</em>
</td>
<td>
<em>(Optional)</em>
<p>ServiceClusterIPs are the CIDR blocks from which service cluster IPs are allocated.</p>
</td>
</tr>
<tr>
<td>
<code>bgpPeer</code></br>
<em>
<a href="#metal.provider.extensions.gardener.cloud/v1alpha1.BgpPeer">
[]BgpPeer
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>BGPPeer contains configuration for BGPPeer resource.</p>
</td>
</tr>
</tbody>
</table>
<h3 id="metal.provider.extensions.gardener.cloud/v1alpha1.CloudControllerManagerConfig">CloudControllerManagerConfig
</h3>
<p>
@@ -257,6 +390,20 @@ MetallbConfig
<p>MetallbConfig contains configuration settings for metallb.</p>
</td>
</tr>
<tr>
<td>
<code>calicoBgpConfig</code></br>
<em>
<a href="#metal.provider.extensions.gardener.cloud/v1alpha1.CalicoBgpConfig">
CalicoBgpConfig
</a>
</em>
</td>
<td>
<em>(Optional)</em>
<p>CalicoBgpConfig contains configuration settings for calico.</p>
</td>
</tr>
</tbody>
</table>
<h3 id="metal.provider.extensions.gardener.cloud/v1alpha1.MachineImage">MachineImage
33 changes: 33 additions & 0 deletions pkg/apis/metal/types_controlplane.go
Original file line number Diff line number Diff line change
@@ -31,6 +31,9 @@ type CloudControllerManagerConfig struct {
type LoadBalancerConfig struct {
// MetallbConfig contains configuration settings for metallb.
MetallbConfig *MetallbConfig

// CalicoBgpConfig contains configuration settings for calico.
CalicoBgpConfig *CalicoBgpConfig
}

// MetallbConfig contains configuration settings for metallb.
@@ -44,3 +47,33 @@ type MetallbConfig struct {
// EnableL2Advertisement enables L2 advertisement.
EnableL2Advertisement bool
}

// CalicoBgpConfig contains BGP configuration settings for calico.
type CalicoBgpConfig struct {
// ASNumber is the default AS number used by a node.
ASNumber int

// ServiceLoadBalancerIPs are the CIDR blocks for Kubernetes Service LoadBalancer IPs.
ServiceLoadBalancerIPs []string

// ServiceExternalIPs are the CIDR blocks for Kubernetes Service External IPs.
ServiceExternalIPs []string

// ServiceClusterIPs are the CIDR blocks from which service cluster IPs are allocated.
ServiceClusterIPs []string

// BGPPeer contains configuration for BGPPeer resource.
BgpPeer []BgpPeer
}

// BgpPeer contains configuration for BGPPeer resource.
type BgpPeer struct {
// PeerIP contains IP address of BGP peer followed by an optional port number to peer with.
PeerIP string

// ASNumber contains the AS number of the BGP peer.
ASNumber int

// NodeSelector is a key-value pair to select nodes that should have this peering.
NodeSelector string
}
42 changes: 42 additions & 0 deletions pkg/apis/metal/v1alpha1/types_controlplane.go
Original file line number Diff line number Diff line change
@@ -35,6 +35,10 @@ type LoadBalancerConfig struct {
// MetallbConfig contains configuration settings for metallb.
// +optional
MetallbConfig *MetallbConfig `json:"metallbConfig,omitempty"`

// CalicoBgpConfig contains configuration settings for calico.
// +optional
CalicoBgpConfig *CalicoBgpConfig `json:"calicoBgpConfig,omitempty"`
}

// MetallbConfig contains configuration settings for metallb.
@@ -51,3 +55,41 @@ type MetallbConfig struct {
// +optional
EnableL2Advertisement bool `json:"enableL2Advertisement,omitempty"`
}

// CalicoBgpConfig contains BGP configuration settings for calico.
type CalicoBgpConfig struct {
// ASNumber is the default AS number used by a node.
// +required
ASNumber int `json:"asNumber"`

// ServiceLoadBalancerIPs are the CIDR blocks for Kubernetes Service LoadBalancer IPs.
// +optional
ServiceLoadBalancerIPs []string `json:"serviceLoadBalancerIPs,omitempty"`

// ServiceExternalIPs are the CIDR blocks for Kubernetes Service External IPs.
// +optional
ServiceExternalIPs []string `json:"serviceExternalIPs,omitempty"`

// ServiceClusterIPs are the CIDR blocks from which service cluster IPs are allocated.
// +optional
ServiceClusterIPs []string `json:"serviceClusterIPs,omitempty"`

// BGPPeer contains configuration for BGPPeer resource.
// +optional
BgpPeer []BgpPeer `json:"bgpPeer,omitempty"`
}

// BgpPeer contains configuration for BGPPeer resource.
type BgpPeer struct {
// PeerIP contains IP address of BGP peer followed by an optional port number to peer with.
// +required
PeerIP string `json:"peerIP"`

// ASNumber contains the AS number of the BGP peer.
// +required
ASNumber int `json:"asNumber"`

// NodeSelector is a key-value pair to select nodes that should have this peering.
// +optional
NodeSelector string `json:"nodeSelector,omitempty"`
}
74 changes: 74 additions & 0 deletions pkg/apis/metal/v1alpha1/zz_generated.conversion.go
57 changes: 57 additions & 0 deletions pkg/apis/metal/v1alpha1/zz_generated.deepcopy.go
57 changes: 57 additions & 0 deletions pkg/apis/metal/zz_generated.deepcopy.go
73 changes: 72 additions & 1 deletion pkg/controller/controlplane/valuesprovider.go
Original file line number Diff line number Diff line change
@@ -342,13 +342,20 @@ func (vp *valuesProvider) getControlPlaneShootChartValues(cluster *extensionscon
if err != nil {
return nil, err
}

calicoBgp, err := getCalicoBgpChartValues(cp, cluster)
if err != nil {
return nil, err
}

return map[string]any{
metal.CloudControllerManagerName: map[string]any{"enabled": true},
metal.MetallbName: metallb,
metal.CalicoBgpName: calicoBgp,
}, nil
}

// getMetallbChartValues collects and returns the CCM chart values.
// getMetallbChartValues collects and returns the MetalLB chart values.
func getMetallbChartValues(
cpConfig *apismetal.ControlPlaneConfig,
) (map[string]any, error) {
@@ -376,6 +383,70 @@ func getMetallbChartValues(
}, nil
}

// getCalicoBgpChartValues collects and returns the Calico BGP chart values.
func getCalicoBgpChartValues(
cpConfig *apismetal.ControlPlaneConfig,
cluster *extensionscontroller.Cluster,
) (map[string]any, error) {
if cpConfig.LoadBalancerConfig == nil || cpConfig.LoadBalancerConfig.CalicoBgpConfig == nil {
return map[string]any{
"enabled": false,
}, nil
}

var serviceLbIPs, serviceExtIPs, serviceClusterIPs []string
var peers []map[string]any
if cpConfig.LoadBalancerConfig.CalicoBgpConfig != nil &&
*cluster.Shoot.Spec.Networking.Type == metal.ShootCalicoNetworkType {
if cpConfig.LoadBalancerConfig.CalicoBgpConfig.ServiceLoadBalancerIPs != nil {
for _, cidr := range cpConfig.LoadBalancerConfig.CalicoBgpConfig.ServiceLoadBalancerIPs {
if err := parseAddressPool(cidr); err != nil {
return nil, fmt.Errorf("invalid CIDR %q in pool: %w", cidr, err)
}
serviceLbIPs = append(serviceLbIPs, cidr)
}
}

if cpConfig.LoadBalancerConfig.CalicoBgpConfig.ServiceExternalIPs != nil {
for _, cidr := range cpConfig.LoadBalancerConfig.CalicoBgpConfig.ServiceExternalIPs {
if err := parseAddressPool(cidr); err != nil {
return nil, fmt.Errorf("invalid CIDR %q in pool: %w", cidr, err)
}
serviceExtIPs = append(serviceExtIPs, cidr)
}
}

if cpConfig.LoadBalancerConfig.CalicoBgpConfig.ServiceClusterIPs != nil {
for _, cidr := range cpConfig.LoadBalancerConfig.CalicoBgpConfig.ServiceClusterIPs {
if err := parseAddressPool(cidr); err != nil {
return nil, fmt.Errorf("invalid CIDR %q in pool: %w", cidr, err)
}
serviceClusterIPs = append(serviceClusterIPs, cidr)
}
}

if cpConfig.LoadBalancerConfig.CalicoBgpConfig.BgpPeer != nil {
for _, peer := range cpConfig.LoadBalancerConfig.CalicoBgpConfig.BgpPeer {
peers = append(peers, map[string]any{
"peerIP": peer.PeerIP,
"asNumber": peer.ASNumber,
"nodeSelector": peer.NodeSelector,
})
}
}
}
return map[string]any{
"enabled": true,
"bgp": map[string]any{
"asNumber": cpConfig.LoadBalancerConfig.CalicoBgpConfig.ASNumber,
"serviceLoadBalancerIPs": serviceLbIPs,
"serviceExternalIPs": serviceExtIPs,
"serviceClusterIPs": serviceClusterIPs,
"bgpPeer": peers,
},
}, nil
}

func parseAddressPool(cidr string) error {
if !strings.Contains(cidr, "-") {
_, _, err := net.ParseCIDR(cidr)
118 changes: 118 additions & 0 deletions pkg/controller/controlplane/valuesprovider_test.go
Original file line number Diff line number Diff line change
@@ -287,6 +287,9 @@ var _ = Describe("Valueprovider Reconcile", func() {
"metallb": map[string]any{
"enabled": false,
},
"calico-bgp": map[string]any{
"enabled": false,
},
}))
})
})
@@ -379,6 +382,121 @@ var _ = Describe("Valueprovider Reconcile", func() {
},
"ipAddressPool": []string{"10.10.10.0/24", "10.20.20.10-10.20.20.30"},
},
"calico-bgp": map[string]any{
"enabled": false,
},
}))
})
})

Describe("#GetControlPlaneShootChartValues", func() {
It("should return correct shoot system chart values with calico", func(ctx SpecContext) {
cp := &extensionsv1alpha1.ControlPlane{
ObjectMeta: metav1.ObjectMeta{
Name: "control-plane",
Namespace: ns.Name,
},
Spec: extensionsv1alpha1.ControlPlaneSpec{
Region: "foo",
SecretRef: corev1.SecretReference{
Name: "my-infra-creds",
Namespace: ns.Name,
},
DefaultSpec: extensionsv1alpha1.DefaultSpec{
Type: metal.Type,
ProviderConfig: &runtime.RawExtension{
Raw: encode(&apismetal.ControlPlaneConfig{
CloudControllerManager: &apismetal.CloudControllerManagerConfig{
FeatureGates: map[string]bool{
"CustomResourceValidation": true,
},
},
LoadBalancerConfig: &apismetal.LoadBalancerConfig{
CalicoBgpConfig: &apismetal.CalicoBgpConfig{
ASNumber: 12345,
ServiceLoadBalancerIPs: []string{"10.10.10.0/24", "10.20.20.10-10.20.20.30"},
ServiceClusterIPs: []string{"10.10.10.0/24", "10.20.20.10-10.20.20.30"},
ServiceExternalIPs: []string{"10.10.10.0/24", "10.20.20.10-10.20.20.30"},
BgpPeer: []apismetal.BgpPeer{
{
PeerIP: "1.2.3.4",
ASNumber: 12345,
NodeSelector: "foo=bar",
},
},
},
},
}),
},
},
},
}
Expect(k8sClient.Create(ctx, cp)).To(Succeed())

providerCloudProfile := &apismetal.CloudProfileConfig{}
providerCloudProfileJson, err := json.Marshal(providerCloudProfile)
Expect(err).NotTo(HaveOccurred())
networkProviderConfig := &unstructured.Unstructured{Object: map[string]any{
"kind": "FooNetworkConfig",
"apiVersion": "v1alpha1",
"overlay": map[string]any{
"enabled": false,
},
}}
networkProviderConfigData, err := runtime.Encode(unstructured.UnstructuredJSONScheme, networkProviderConfig)
Expect(err).NotTo(HaveOccurred())
cluster := &controller.Cluster{
CloudProfile: &gardencorev1beta1.CloudProfile{
Spec: gardencorev1beta1.CloudProfileSpec{
ProviderConfig: &runtime.RawExtension{
Raw: providerCloudProfileJson,
},
},
},
Shoot: &gardencorev1beta1.Shoot{
ObjectMeta: metav1.ObjectMeta{
Namespace: ns.Name,
Name: "my-shoot",
},
Spec: gardencorev1beta1.ShootSpec{
Networking: &gardencorev1beta1.Networking{
Type: ptr.To[string](metal.ShootCalicoNetworkType),
ProviderConfig: &runtime.RawExtension{Raw: networkProviderConfigData},
Pods: ptr.To[string]("10.0.0.0/16"),
},
Kubernetes: gardencorev1beta1.Kubernetes{
Version: "1.26.0",
VerticalPodAutoscaler: &gardencorev1beta1.VerticalPodAutoscaler{
Enabled: true,
},
},
},
},
}

values, err := vp.GetControlPlaneShootChartValues(ctx, cp, cluster, fakeSecretsManager, nil)
Expect(err).NotTo(HaveOccurred())
Expect(values).To(Equal(map[string]any{
"cloud-controller-manager": map[string]any{"enabled": true},
"metallb": map[string]any{
"enabled": false,
},
"calico-bgp": map[string]any{
"enabled": true,
"bgp": map[string]any{
"asNumber": 12345,
"serviceLoadBalancerIPs": []string{"10.10.10.0/24", "10.20.20.10-10.20.20.30"},
"serviceExternalIPs": []string{"10.10.10.0/24", "10.20.20.10-10.20.20.30"},
"serviceClusterIPs": []string{"10.10.10.0/24", "10.20.20.10-10.20.20.30"},
"bgpPeer": []map[string]any{
{
"peerIP": "1.2.3.4",
"asNumber": 12345,
"nodeSelector": "foo=bar",
},
},
},
},
}))
})
})
4 changes: 4 additions & 0 deletions pkg/metal/types.go
Original file line number Diff line number Diff line change
@@ -47,10 +47,14 @@ const (
CloudProviderConfigName = "cloud-provider-config"
// CloudControllerManagerName is a constant for the name of the CloudController deployed by the worker controller.
CloudControllerManagerName = "cloud-controller-manager"
// CalicoBgpName is a constant for the name of the Calico BGP deployed by the worker controller.
CalicoBgpName = "calico-bgp"
// MetallbName is a constant for the name of the MetalLB deployed by the worker controller.
MetallbName = "metallb"
// MachineControllerManagerName is a constant for the name of the machine-controller-manager.
MachineControllerManagerName = "machine-controller-manager"
// ShootCalicoNetworkType is the network type for calico in a shoot.
ShootCalicoNetworkType = "calico"
// MachineControllerManagerVpaName is the name of the VerticalPodAutoscaler of the machine-controller-manager deployment.
MachineControllerManagerVpaName = "machine-controller-manager-vpa"
// MachineControllerManagerMonitoringConfigName is the name of the ConfigMap containing monitoring stack configurations for machine-controller-manager.

0 comments on commit 7fd1f02

Please sign in to comment.