mirror of
https://github.com/techno-tim/k3s-ansible.git
synced 2026-08-08 23:13:19 +02:00
feat(metallb): add option to limit MetalLB layer2 announcements to specific interfaces (#696)
- roles/k3s_server_post/templates/metallb.crs.j2: render spec.interfaces in the L2Advertisement when metal_lb_interfaces is a non-empty list, so MetalLB only announces on the configured interfaces. Empty list (default) keeps announcing on all interfaces, preserving existing behavior. - roles/k3s_server_post/defaults/main.yml: add metal_lb_interfaces: [] default - roles/k3s_server_post/meta/main.yml: add metal_lb_interfaces argument_spec - inventory/sample/group_vars/all.yml: document the new sample variable - .github/scripts/test-metallb-interfaces.py: regression test rendering the template for empty/single/multiple interfaces and confirming the BGP path is unaffected - .pre-commit-config.yaml: wire the new test into pre-commit Co-authored-by: Leo <leo@kuboschek.me>
This commit is contained in:
@@ -0,0 +1,88 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Regression test for the MetalLB L2Advertisement interfaces.
|
||||||
|
|
||||||
|
`metal_lb_interfaces` restricts which network interfaces MetalLB announces
|
||||||
|
load balancer IPs on in layer2 mode. When the list is non-empty, the
|
||||||
|
L2Advertisement in roles/k3s_server_post/templates/metallb.crs.j2 must render
|
||||||
|
a `spec.interfaces` block; when it is empty (the default), no spec is rendered
|
||||||
|
so MetalLB announces on all interfaces.
|
||||||
|
|
||||||
|
This renders the template and asserts both cases plus the BGP path (which must
|
||||||
|
not be affected by the L2 interfaces variable).
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from jinja2 import Environment, FileSystemLoader, StrictUndefined
|
||||||
|
|
||||||
|
|
||||||
|
def repo_root():
|
||||||
|
return subprocess.check_output(
|
||||||
|
["git", "rev-parse", "--show-toplevel"], text=True
|
||||||
|
).strip()
|
||||||
|
|
||||||
|
|
||||||
|
def fail(message):
|
||||||
|
raise SystemExit("MetalLB interfaces test failed: " + message)
|
||||||
|
|
||||||
|
|
||||||
|
def render(env, extra_vars):
|
||||||
|
base_vars = {
|
||||||
|
"metal_lb_mode": "layer2",
|
||||||
|
"metal_lb_ip_range": "192.168.30.80-192.168.30.90",
|
||||||
|
}
|
||||||
|
base_vars.update(extra_vars)
|
||||||
|
template = env.get_template("metallb.crs.j2")
|
||||||
|
return template.render(**base_vars)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
root = repo_root()
|
||||||
|
template_dir = os.path.join(
|
||||||
|
root, "roles", "k3s_server_post", "templates"
|
||||||
|
)
|
||||||
|
env = Environment(
|
||||||
|
loader=FileSystemLoader(template_dir), undefined=StrictUndefined
|
||||||
|
)
|
||||||
|
|
||||||
|
# Empty list (default): no spec.interfaces in the L2Advertisement.
|
||||||
|
output = render(env, {"metal_lb_interfaces": []})
|
||||||
|
if "spec:\n interfaces:" in output:
|
||||||
|
fail("spec.interfaces rendered with an empty metal_lb_interfaces")
|
||||||
|
if "kind: L2Advertisement" not in output:
|
||||||
|
fail("L2Advertisement missing in layer2 mode")
|
||||||
|
|
||||||
|
# Single interface.
|
||||||
|
output = render(env, {"metal_lb_interfaces": ["eth1"]})
|
||||||
|
if "spec:\n interfaces:\n - eth1" not in output:
|
||||||
|
fail("single interface was not rendered in spec.interfaces")
|
||||||
|
|
||||||
|
# Multiple interfaces.
|
||||||
|
output = render(env, {"metal_lb_interfaces": ["eth1", "eth2"]})
|
||||||
|
if "spec:\n interfaces:\n - eth1\n - eth2" not in output:
|
||||||
|
fail("multiple interfaces were not rendered in spec.interfaces")
|
||||||
|
|
||||||
|
# BGP mode must not emit an L2Advertisement spec at all.
|
||||||
|
output = render(
|
||||||
|
env,
|
||||||
|
{
|
||||||
|
"metal_lb_mode": "bgp",
|
||||||
|
"metal_lb_interfaces": ["eth1"],
|
||||||
|
"metal_lb_bgp_my_asn": "64513",
|
||||||
|
"metal_lb_bgp_peer_asn": "64512",
|
||||||
|
"metal_lb_bgp_peer_address": "192.168.30.1",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if "kind: L2Advertisement" in output:
|
||||||
|
fail("L2Advertisement rendered in bgp mode")
|
||||||
|
if "interfaces:" in output:
|
||||||
|
fail("interfaces rendered in bgp mode")
|
||||||
|
|
||||||
|
print("MetalLB interfaces regression test passed")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -93,6 +93,14 @@ repos:
|
|||||||
language: system
|
language: system
|
||||||
pass_filenames: false
|
pass_filenames: false
|
||||||
files: ^roles/k3s_server/tasks/metallb\.yml$|^\.github/scripts/test-metallb-remote-read\.sh$
|
files: ^roles/k3s_server/tasks/metallb\.yml$|^\.github/scripts/test-metallb-remote-read\.sh$
|
||||||
|
- id: metallb-interfaces-test
|
||||||
|
name: MetalLB interfaces test
|
||||||
|
entry: python3 .github/scripts/test-metallb-interfaces.py
|
||||||
|
language: python
|
||||||
|
additional_dependencies:
|
||||||
|
- Jinja2>=3.1
|
||||||
|
pass_filenames: false
|
||||||
|
files: ^roles/k3s_server_post/templates/metallb\.crs\.j2$|^\.github/scripts/test-metallb-interfaces\.py$
|
||||||
- id: metallb-deploy-condition-test
|
- id: metallb-deploy-condition-test
|
||||||
name: MetalLB deploy condition test
|
name: MetalLB deploy condition test
|
||||||
entry: python3 .github/scripts/test-metallb-deploy-condition.py
|
entry: python3 .github/scripts/test-metallb-deploy-condition.py
|
||||||
|
|||||||
@@ -120,6 +120,12 @@ metal_lb_controller_tag_version: v0.16.0
|
|||||||
# metallb ip range for load balancer
|
# metallb ip range for load balancer
|
||||||
metal_lb_ip_range: 192.168.30.80-192.168.30.90
|
metal_lb_ip_range: 192.168.30.80-192.168.30.90
|
||||||
|
|
||||||
|
# (optional) limit MetalLB layer2 announcements to specific network interfaces.
|
||||||
|
# Leave empty (default) to announce on all interfaces.
|
||||||
|
# metal_lb_interfaces:
|
||||||
|
# - eth1
|
||||||
|
# - eth2
|
||||||
|
|
||||||
# Only enable if your nodes are proxmox LXC nodes, make sure to configure your proxmox nodes
|
# Only enable if your nodes are proxmox LXC nodes, make sure to configure your proxmox nodes
|
||||||
# in your hosts.ini file.
|
# in your hosts.ini file.
|
||||||
# Please read https://gist.github.com/triangletodd/02f595cd4c0dc9aac5f7763ca2264185 before using this.
|
# Please read https://gist.github.com/triangletodd/02f595cd4c0dc9aac5f7763ca2264185 before using this.
|
||||||
|
|||||||
@@ -39,4 +39,5 @@ group_name_master: master
|
|||||||
metal_lb_mode: layer2
|
metal_lb_mode: layer2
|
||||||
metal_lb_available_timeout: 240s
|
metal_lb_available_timeout: 240s
|
||||||
metal_lb_controller_tag_version: v0.16.0
|
metal_lb_controller_tag_version: v0.16.0
|
||||||
|
metal_lb_interfaces: []
|
||||||
metal_lb_ip_range: 192.168.30.80-192.168.30.90
|
metal_lb_ip_range: 192.168.30.80-192.168.30.90
|
||||||
|
|||||||
@@ -141,6 +141,14 @@ argument_specs:
|
|||||||
description: MetalLB ip range for load balancer
|
description: MetalLB ip range for load balancer
|
||||||
default: 192.168.30.80-192.168.30.90
|
default: 192.168.30.80-192.168.30.90
|
||||||
|
|
||||||
|
metal_lb_interfaces:
|
||||||
|
description: >-
|
||||||
|
List of network interfaces on which MetalLB should announce the
|
||||||
|
load balancer IPs in layer2 mode. When empty (default), MetalLB
|
||||||
|
announces on all interfaces.
|
||||||
|
type: list
|
||||||
|
default: []
|
||||||
|
|
||||||
metal_lb_controller_tag_version:
|
metal_lb_controller_tag_version:
|
||||||
description: Image tag for MetalLB
|
description: Image tag for MetalLB
|
||||||
default: v0.16.0
|
default: v0.16.0
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ kind: L2Advertisement
|
|||||||
metadata:
|
metadata:
|
||||||
name: default
|
name: default
|
||||||
namespace: metallb-system
|
namespace: metallb-system
|
||||||
|
{% if metal_lb_interfaces | default([]) | length > 0 %}
|
||||||
|
spec:
|
||||||
|
interfaces:{% for iface in metal_lb_interfaces %}
|
||||||
|
- {{ iface }}{% endfor %}
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if metal_lb_mode == "bgp" %}
|
{% if metal_lb_mode == "bgp" %}
|
||||||
---
|
---
|
||||||
|
|||||||
Reference in New Issue
Block a user