⚠️ Work in Progress
You are viewing development documentation built from the latest commit on main. APIs and features are subject to change.

MetalLB Builders

MetalLB Builders - MetalLB Resource Constructors

Go Reference Go Reference

The metallb package provides strongly-typed constructor functions for creating MetalLB Kubernetes resources. These are the low-level building blocks used by Kure’s higher-level stack and workflow packages.

Overview

Each generated constructor returns a MetalLB custom resource carrying its API version, kind and identity, and nothing else. You set the spec yourself, by assignment or through the admissible sugar this package exports.

Each block on this page is the body of an Example function in example_test.go, which go test runs: it imports this package as metallb, the upstream API as metallbv1beta1 "go.universe.tf/metallb/api/v1beta1", the apimachinery meta types as metav1 "k8s.io/apimachinery/pkg/apis/meta/v1", and fmt for the line that prints what the example built.

Constructors

Every kind this package registers, except BGPPeer at the deprecated metallb.io/v1beta1 (see BGP Peers ), has a generated Create<Kind> wrapper in zz_generated_create.go, produced from the scheme by pkg/kubernetes/internal/gen (make gen-builders, checked by make check-builders in CI). A wrapper delegates to kubernetes.Create[T] and emits TypeMeta and identity only: no default, no label, no spec value. Namespaced kinds take (name, namespace), cluster-scoped kinds take (name). The upstream struct is the construction API; set spec fields directly or through the admissible Set*/Add* sugar below.

obj := metallb.CreateIPAddressPool("my-pool", "metallb-system")
fmt.Println(obj.Kind, obj.Namespace+"/"+obj.Name)

This package never had a config-struct layer: no metallb.<Kind>(&metallb.<Kind>Config{...}) builder existed here even before release 2 of the builder contract retired that layer everywhere else — the generated constructor plus field assignment has always been the whole construction API. No hand-written Create* helper for a spec fragment remains either: a sub-type that is not a client.Object takes a struct literal, which is shorter and shows every field being set.

The kinds this package registers, their scope, and what stated that scope are rows in the generated Supported kinds and field maturity tables. The sections below are worked examples, not the coverage list.

See the Kubernetes Builders page for the full builder contract: construction, sugar admission classes, purity and the release-1 migration ledger.

Supported Resources

IP Address Pools

pool := metallb.CreateIPAddressPool("my-pool", "metallb-system")
metallb.AddIPAddressPoolAddress(pool, "192.168.1.0/24")
metallb.AddIPAddressPoolAddress(pool, "10.0.0.0/16")
fmt.Println(pool.Spec.Addresses)

BGP Peers

MetalLB serves BGPPeer at two versions: metallb.io/v1beta1, which it deprecates, and metallb.io/v1beta2, the one it stores. CreateBGPPeer returns the v1beta2 object (go.universe.tf/metallb/api/v1beta2), and AddBGPPeerNodeSelector takes that object and a metav1.LabelSelector, the selector type the advertisement kinds already use.

Both versions are registered, so a manifest at either one parses to its own typed object. Only v1beta2 has a constructor: a wrapper is named after its kind, and one package cannot hold two CreateBGPPeer. To build a v1beta1 object, name the upstream type: kubernetes.Create[metallbv1beta1.BGPPeer](name, namespace), the generic form every wrapper calls, or the struct itself with its TypeMeta set. kure does not convert between the two.

peer := metallb.CreateBGPPeer("my-peer", "metallb-system")
peer.Spec.MyASN = 64500
peer.Spec.ASN = 64501
peer.Spec.Address = "10.0.0.1"
peer.Spec.Port = 179
metallb.AddBGPPeerNodeSelector(peer, metav1.LabelSelector{
    MatchLabels: map[string]string{"node-role.kubernetes.io/worker": ""},
})
fmt.Println(peer.APIVersion, peer.Spec.Address, peer.Spec.ASN, len(peer.Spec.NodeSelectors))

BGP Advertisements

advert := metallb.CreateBGPAdvertisement("my-advert", "metallb-system")
metallb.AddBGPAdvertisementIPAddressPool(advert, "my-pool")
metallb.AddBGPAdvertisementPeer(advert, "my-peer")
metallb.AddBGPAdvertisementCommunity(advert, "65535:65282")
advert.Spec.LocalPref = 100
fmt.Println(advert.Spec.IPAddressPools, advert.Spec.Peers, advert.Spec.Communities)

L2 Advertisements

l2 := metallb.CreateL2Advertisement("my-l2", "metallb-system")
metallb.AddL2AdvertisementIPAddressPool(l2, "my-pool")
metallb.AddL2AdvertisementInterface(l2, "eth0")
fmt.Println(l2.Spec.IPAddressPools, l2.Spec.Interfaces)

BFD Profiles

bfd := metallb.CreateBFDProfile("my-bfd", "metallb-system")
metallb.SetBFDProfileDetectMultiplier(bfd, 3)
fmt.Println(*bfd.Spec.DetectMultiplier)

Modifier Functions

Update existing resources:

pool := metallb.CreateIPAddressPool("my-pool", "metallb-system")
peer := metallb.CreateBGPPeer("my-peer", "metallb-system")

// Replace the full spec
pool.Spec = metallbv1beta1.IPAddressPoolSpec{Addresses: []string{"192.168.1.0/24"}}

// Plain fields are assigned directly — there is no Set<Kind><Field> helper
peer.Spec.Port = 1179

// Slice fields keep an appender, and pointer fields a setter
metallb.AddIPAddressPoolAddress(pool, "172.16.0.0/12")
metallb.SetIPAddressPoolAutoAssign(pool, false)

fmt.Println(pool.Spec.Addresses, *pool.Spec.AutoAssign, peer.Spec.Port)

The helpers are void. A nil object is a programming error and panics, like every other builder in this family.