From 0a83a824d71e6260542a8b1bacd2ab5449d6804f Mon Sep 17 00:00:00 2001 From: Stefan Majer Date: Wed, 15 Jan 2025 09:29:36 +0100 Subject: [PATCH 1/2] Only add no bgp enforce-first-as on frr >= 10 --- controllers/firewall_controller.go | 5 +++- go.mod | 4 +-- go.sum | 4 +-- main.go | 13 ++++++-- pkg/frr/frr.go | 48 ++++++++++++++++++++++++++++++ pkg/network/network.go | 5 ++-- 6 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 pkg/frr/frr.go diff --git a/controllers/firewall_controller.go b/controllers/firewall_controller.go index 25f80861..b9738e0e 100644 --- a/controllers/firewall_controller.go +++ b/controllers/firewall_controller.go @@ -9,6 +9,7 @@ import ( "strings" "time" + "github.com/Masterminds/semver/v3" "github.com/go-logr/logr" mn "github.com/metal-stack/metal-lib/pkg/net" corev1 "k8s.io/api/core/v1" @@ -49,6 +50,8 @@ type FirewallReconciler struct { recordFirewallEvent func(f *firewallv2.Firewall, eventtype, reason, message string) SeedUpdatedFunc func() + + FrrVersion *semver.Version } const ( @@ -115,7 +118,7 @@ func (r *FirewallReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c r.Log.Info("reconciling network settings") var errs []error - changed, err := network.ReconcileNetwork(f) + changed, err := network.ReconcileNetwork(f, r.FrrVersion) if changed && err == nil { r.recordFirewallEvent(f, corev1.EventTypeNormal, "Network settings", "reconciliation succeeded (frr.conf)") } else if changed && err != nil { diff --git a/go.mod b/go.mod index ea7961bd..6425ae95 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.23.0 toolchain go1.23.4 require ( + github.com/Masterminds/semver/v3 v3.3.1 github.com/coreos/go-systemd/v22 v22.5.0 github.com/fatih/color v1.18.0 github.com/go-logr/logr v1.4.2 @@ -14,7 +15,7 @@ require ( github.com/metal-stack/firewall-controller-manager v0.4.3 github.com/metal-stack/metal-go v0.39.4 github.com/metal-stack/metal-lib v0.19.0 - github.com/metal-stack/metal-networker v0.46.0 + github.com/metal-stack/metal-networker v0.46.1-0.20250115094131-585c24b0d8d7 github.com/metal-stack/v v1.0.3 github.com/miekg/dns v1.1.62 github.com/txn2/txeh v1.5.5 @@ -31,7 +32,6 @@ require ( replace k8s.io/apimachinery => k8s.io/apimachinery v0.29.3 require ( - github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect diff --git a/go.sum b/go.sum index 0da21f4b..5edd957d 100644 --- a/go.sum +++ b/go.sum @@ -117,8 +117,8 @@ github.com/metal-stack/metal-hammer v0.13.10 h1:p1L2rGeABbjv8jRnua7dYF8nDjLZ+Boh github.com/metal-stack/metal-hammer v0.13.10/go.mod h1:cOdArIOW1VBICPX3dlpyg1Wf3PsMeGjyw7mJJmCTqeU= github.com/metal-stack/metal-lib v0.19.0 h1:4yBnp/jPGgX9KeCje3A4MFL2oDjgjOjgsIK391LltRI= github.com/metal-stack/metal-lib v0.19.0/go.mod h1:fCMaWwVGA/xAoGvBk72/nfzqBkHly0iOzrWpc55Fau4= -github.com/metal-stack/metal-networker v0.46.0 h1:fRC+LHRWvvYK9ernI6Wasr9wPseVS1s9q7PAVV3JZKc= -github.com/metal-stack/metal-networker v0.46.0/go.mod h1:C2bsFq4o6p6GwGS2j14/r+nwKGpGSl3uIISzPrhO8+A= +github.com/metal-stack/metal-networker v0.46.1-0.20250115094131-585c24b0d8d7 h1:ObBqtlHOjEQLegHUhY8mFhR3cDEt8zgDMGe68u+5gMQ= +github.com/metal-stack/metal-networker v0.46.1-0.20250115094131-585c24b0d8d7/go.mod h1:FyG88QowtyZ7J2bBf36HRZsdm7JK1HCNVNrCMU7THQA= github.com/metal-stack/v v1.0.3 h1:Sh2oBlnxrCUD+mVpzfC8HiqL045YWkxs0gpTvkjppqs= github.com/metal-stack/v v1.0.3/go.mod h1:YTahEu7/ishwpYKnp/VaW/7nf8+PInogkfGwLcGPdXg= github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= diff --git a/main.go b/main.go index a210c1c5..4029390d 100644 --- a/main.go +++ b/main.go @@ -29,6 +29,7 @@ import ( firewallv1 "github.com/metal-stack/firewall-controller/v2/api/v1" "github.com/metal-stack/firewall-controller/v2/controllers" + "github.com/metal-stack/firewall-controller/v2/pkg/frr" "github.com/metal-stack/firewall-controller/v2/pkg/sysctl" "github.com/metal-stack/firewall-controller/v2/pkg/updater" // +kubebuilder:scaffold:imports @@ -211,8 +212,6 @@ func main() { panic(err) } - updater := updater.New(ctrl.Log.WithName("updater"), shootMgr.GetEventRecorderFor("FirewallController")) - fwmReconciler := &controllers.FirewallMonitorReconciler{ ShootClient: shootMgr.GetClient(), Log: ctrl.Log.WithName("controllers").WithName("FirewallMonitorReconciler"), @@ -222,6 +221,15 @@ func main() { Namespace: firewallv2.FirewallShootNamespace, } + frrVersion, err := frr.DetectVersion() + if err != nil { + l.Error("frr version detection", "error", err) + panic(err) + } + l.Info("detected frr", "version", frrVersion.String()) + + updater := updater.New(ctrl.Log.WithName("updater"), shootMgr.GetEventRecorderFor("FirewallController")) + // Firewall Reconciler if err = (&controllers.FirewallReconciler{ SeedClient: seedMgr.GetClient(), @@ -234,6 +242,7 @@ func main() { Updater: updater, SeedUpdatedFunc: fwmReconciler.SeedUpdated, TokenUpdater: accessTokenUpdater, + FrrVersion: frrVersion, }).SetupWithManager(seedMgr); err != nil { l.Error("unable to create firewall controller", "error", err) panic(err) diff --git a/pkg/frr/frr.go b/pkg/frr/frr.go new file mode 100644 index 00000000..53b517ef --- /dev/null +++ b/pkg/frr/frr.go @@ -0,0 +1,48 @@ +package frr + +import ( + "fmt" + "os/exec" + "strings" + + "github.com/Masterminds/semver/v3" +) + +func DetectVersion() (*semver.Version, error) { + + vtysh, err := exec.LookPath("vtysh") + if err != nil { + return nil, fmt.Errorf("unable to detect path to vtysh: %w", err) + } + // $ vtysh -c "show version"|grep FRRouting + // FRRouting 10.2.1 (shoot--pz9cjf--mwen-fel-firewall-dcedd) on Linux(6.6.60-060660-generic). + c := exec.Command(vtysh, "-c", "show version") + out, err := c.CombinedOutput() + if err != nil { + return nil, fmt.Errorf("unable to detect frr version with dpkg: %w", err) + } + + var frrVersion string + for _, line := range strings.Split(string(out), "\n") { + if !strings.Contains(line, "FRRouting") { + continue + } + + fields := strings.Fields(line) + if len(fields) < 2 { + continue + } + + frrVersion = fields[1] + break + } + if frrVersion == "" { + return nil, fmt.Errorf("unable to detect frr version") + } + + ver, err := semver.NewVersion(frrVersion) + if err != nil { + return nil, fmt.Errorf("unable to parse frr version to semver: %w", err) + } + return ver, nil +} diff --git a/pkg/network/network.go b/pkg/network/network.go index 9090303d..c137c844 100644 --- a/pkg/network/network.go +++ b/pkg/network/network.go @@ -6,6 +6,7 @@ import ( "os" "path/filepath" + "github.com/Masterminds/semver/v3" firewallv2 "github.com/metal-stack/firewall-controller-manager/api/v2" "github.com/metal-stack/metal-go/api/models" "github.com/metal-stack/metal-networker/pkg/netconf" @@ -55,7 +56,7 @@ func GetNewNetworks(f *firewallv2.Firewall, oldNetworks []*models.V1MachineNetwo // ReconcileNetwork reconciles the network settings for a firewall // Changes both the FRR-Configuration and Nftable rules when network prefixes or FRR template changes -func ReconcileNetwork(f *firewallv2.Firewall) (changed bool, err error) { +func ReconcileNetwork(f *firewallv2.Firewall, frrVersion *semver.Version) (changed bool, err error) { tmpFile, err := tmpFile(frrConfig) if err != nil { return false, fmt.Errorf("error during network reconciliation %v: %w", tmpFile, err) @@ -70,7 +71,7 @@ func ReconcileNetwork(f *firewallv2.Firewall) (changed bool, err error) { } c.Networks = GetNewNetworks(f, c.Networks) - a := netconf.NewFrrConfigApplier(netconf.Firewall, *c, tmpFile) + a := netconf.NewFrrConfigApplier(netconf.Firewall, *c, tmpFile, frrVersion) tpl := netconf.MustParseTpl(netconf.TplFirewallFRR) changed, err = a.Apply(*tpl, tmpFile, frrConfig, true) From 5df4970a733b287ad6e546fb28ec9c2db34f57f4 Mon Sep 17 00:00:00 2001 From: Stefan Majer Date: Wed, 15 Jan 2025 12:41:55 +0100 Subject: [PATCH 2/2] Pin metal-networker --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6425ae95..d3766043 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/metal-stack/firewall-controller-manager v0.4.3 github.com/metal-stack/metal-go v0.39.4 github.com/metal-stack/metal-lib v0.19.0 - github.com/metal-stack/metal-networker v0.46.1-0.20250115094131-585c24b0d8d7 + github.com/metal-stack/metal-networker v0.46.1 github.com/metal-stack/v v1.0.3 github.com/miekg/dns v1.1.62 github.com/txn2/txeh v1.5.5 diff --git a/go.sum b/go.sum index 5edd957d..bd01f85a 100644 --- a/go.sum +++ b/go.sum @@ -117,8 +117,8 @@ github.com/metal-stack/metal-hammer v0.13.10 h1:p1L2rGeABbjv8jRnua7dYF8nDjLZ+Boh github.com/metal-stack/metal-hammer v0.13.10/go.mod h1:cOdArIOW1VBICPX3dlpyg1Wf3PsMeGjyw7mJJmCTqeU= github.com/metal-stack/metal-lib v0.19.0 h1:4yBnp/jPGgX9KeCje3A4MFL2oDjgjOjgsIK391LltRI= github.com/metal-stack/metal-lib v0.19.0/go.mod h1:fCMaWwVGA/xAoGvBk72/nfzqBkHly0iOzrWpc55Fau4= -github.com/metal-stack/metal-networker v0.46.1-0.20250115094131-585c24b0d8d7 h1:ObBqtlHOjEQLegHUhY8mFhR3cDEt8zgDMGe68u+5gMQ= -github.com/metal-stack/metal-networker v0.46.1-0.20250115094131-585c24b0d8d7/go.mod h1:FyG88QowtyZ7J2bBf36HRZsdm7JK1HCNVNrCMU7THQA= +github.com/metal-stack/metal-networker v0.46.1 h1:X4UKEom7ZU9sY0ndrqWhtfUDR0jShGauCpBXVSzAocY= +github.com/metal-stack/metal-networker v0.46.1/go.mod h1:FyG88QowtyZ7J2bBf36HRZsdm7JK1HCNVNrCMU7THQA= github.com/metal-stack/v v1.0.3 h1:Sh2oBlnxrCUD+mVpzfC8HiqL045YWkxs0gpTvkjppqs= github.com/metal-stack/v v1.0.3/go.mod h1:YTahEu7/ishwpYKnp/VaW/7nf8+PInogkfGwLcGPdXg= github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=