Repository: metallb/metallb
Pull request #2252 (2024-01-18 08:46:18)

Remove support for legacy AddressPools
The legacy AddressPool API has been deprecated for a while, we finally delete it in favor of supporting only IPAddressPools.

fedepaol: LGTM

Patch:
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 58ea757b..d216464a 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -272,61 +272,6 @@ jobs:
         with:
           artifact-name: kind-logs-${{ matrix.ip-family }}-${{ matrix.bgp-type }}-${{ matrix.deployment}}
 
-  # This lane checks if conversion webhooks work and if metallb is compatible with the CRDs
-  # in the operator. We deploy a v4-frr lane, clone the v0.12.1 version of metallb and run CI
-  # in operator mode. We run few significative tests that cover all the crds.
-  backward_compatible:
-    runs-on: ubuntu-22.04
-    needs:
-      - unit-tests
-      - build-test-images
-      - helm
-      - commitlint
-    steps:
-      - name: Checkout
-        uses: actions/checkout@v4
-        with:
-          fetch-depth: 0
-
-      - name: Setup
-        uses: ./.github/workflows/composite/setup
-
-      - name: Checkout
-        uses: actions/checkout@v4
-        with:
-          fetch-depth: "0"
-          path: metallb-v0.12.1
-          ref: v0.12.1
-
-      - name: Deploy MetalLB
-        run: |
-          inv dev-env -b frr --no-build-images
-      # Patch the old e2etest to cleanup the resources in the correct order.
-      - name: Apply patch
-        run: |
-          patch metallb-v0.12.1/e2etest/pkg/config/update.go < e2etest/backwardcompatible/patchfile
-
-      - name: E2E
-        run: |
-          cat <<EOF | kubectl apply -f -
-          apiVersion: v1
-          kind: ConfigMap
-          metadata:
-            namespace: metallb-system
-            name: config
-          EOF
-          rm -rf e2etest # we want to make sure we are not running current e2e by mistake
-          cd metallb-v0.12.1
-          sed -i -e 's/quay.io\/frrouting\/frr:stable_7.5/quay.io\/frrouting\/frr:7.5.1/g' e2etest/pkg/frr/container/container.go # replace with frr image from dockerhub since it has official image.
-          FOCUS="L2.*should work for ExternalTrafficPolicy=Cluster|BGP.*A service of protocol load balancer should work with.*IPV4 - ExternalTrafficPolicyCluster$|BGP.*should work with the given bfd profile.*IPV4 - default"
-          sudo -E env "PATH=$PATH" inv e2etest --skip-docker --use-operator --focus "$FOCUS" -e /tmp/kind_logs
-
-      - name: Collect Logs
-        if: ${{ failure() }}
-        uses: ./.github/workflows/composite/collectlogs
-        with:
-          artifact-name: kind-logs-backward-compatible
-
   e2e-use-operator:
     runs-on: ubuntu-22.04
     needs:
diff --git a/api/v1alpha1/addresspool_conversion.go b/api/v1alpha1/addresspool_conversion.go
deleted file mode 100644
index db69d6f1..00000000
--- a/api/v1alpha1/addresspool_conversion.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// SPDX-License-Identifier:Apache-2.0
-
-package v1alpha1
-
-import (
-	"go.universe.tf/metallb/api/v1beta1"
-	"go.universe.tf/metallb/internal/pointer"
-	"sigs.k8s.io/controller-runtime/pkg/conversion"
-)
-
-// ConvertTo converts this AddressPool to the Hub version (vbeta1).
-func (src *AddressPool) ConvertTo(dstRaw conversion.Hub) error {
-	dst := dstRaw.(*v1beta1.AddressPool)
-	dst.Spec.Protocol = src.Spec.Protocol
-	dst.Spec.Addresses = make([]string, len(src.Spec.Addresses))
-	copy(dst.Spec.Addresses, src.Spec.Addresses)
-	if src.Spec.AutoAssign != nil {
-		dst.Spec.AutoAssign = pointer.BoolPtr(*src.Spec.AutoAssign)
-	}
-	dst.Spec.BGPAdvertisements = make([]v1beta1.LegacyBgpAdvertisement, len(src.Spec.BGPAdvertisements))
-	for i, adv := range src.Spec.BGPAdvertisements {
-		if adv.AggregationLength != nil {
-			dst.Spec.BGPAdvertisements[i].AggregationLength = pointer.Int32Ptr(*adv.AggregationLength)
-		}
-		if adv.AggregationLengthV6 != nil {
-			dst.Spec.BGPAdvertisements[i].AggregationLengthV6 = pointer.Int32Ptr(*adv.AggregationLengthV6)
-		}
-		dst.Spec.BGPAdvertisements[i].LocalPref = adv.LocalPref
-		dst.Spec.BGPAdvertisements[i].Communities = make([]string, len(adv.Communities))
-		copy(dst.Spec.BGPAdvertisements[i].Communities, adv.Communities)
-	}
-	dst.ObjectMeta = src.ObjectMeta
-	return nil
-}
-
-// ConvertFrom converts from the Hub version (vbeta1) to this version.
-func (dst *AddressPool) ConvertFrom(srcRaw conversion.Hub) error {
-	src := srcRaw.(*v1beta1.AddressPool)
-	dst.ObjectMeta = src.ObjectMeta
-
-	dst.Spec.Protocol = src.Spec.Protocol
-	dst.Spec.Addresses = make([]string, len(src.Spec.Addresses))
-	copy(dst.Spec.Addresses, src.Spec.Addresses)
-	if src.Spec.AutoAssign != nil {
-		dst.Spec.AutoAssign = pointer.BoolPtr(*src.Spec.AutoAssign)
-	}
-	dst.Spec.BGPAdvertisements = make([]BgpAdvertisement, len(src.Spec.BGPAdvertisements))
-	for i, adv := range src.Spec.BGPAdvertisements {
-		if adv.AggregationLength != nil {
-			dst.Spec.BGPAdvertisements[i].AggregationLength = pointer.Int32Ptr(*adv.AggregationLength)
-		}
-		if adv.AggregationLengthV6 != nil {
-			dst.Spec.BGPAdvertisements[i].AggregationLengthV6 = pointer.Int32Ptr(*adv.AggregationLengthV6)
-		}
-		dst.Spec.BGPAdvertisements[i].LocalPref = adv.LocalPref
-		dst.Spec.BGPAdvertisements[i].Communities = make([]string, len(adv.Communities))
-		copy(dst.Spec.BGPAdvertisements[i].Communities, adv.Communities)
-	}
-	return nil
-}
diff --git a/api/v1alpha1/addresspool_types.go b/api/v1alpha1/addresspool_types.go
deleted file mode 100644
index 548ac927..00000000
--- a/api/v1alpha1/addresspool_types.go
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package v1alpha1
-
-import (
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-)
-
-type BgpAdvertisement struct {
-	// The aggregation-length advertisement option lets you “roll up” the /32s into a larger prefix.
-	// +kubebuilder:validation:Minimum=1
-	// +kubebuilder:default:=32
-	// +optional
-	AggregationLength *int32 `json:"aggregationLength,omitempty"`
-
-	// Optional, defaults to 128 (i.e. no aggregation) if not
-	// specified.
-	// +kubebuilder:default:=128
-	// +optional
-	AggregationLengthV6 *int32 `json:"aggregationLengthV6,omitempty"`
-
-	// BGP LOCAL_PREF attribute which is used by BGP best path algorithm,
-	// Path with higher localpref is preferred over one with lower localpref.
-	LocalPref uint32 `json:"localPref,omitempty"`
-
-	// BGP communities
-	Communities []string `json:"communities,omitempty"`
-}
-
-// AddressPoolSpec defines the desired state of AddressPool.
-type AddressPoolSpec struct {
-	// Protocol can be used to select how the announcement is done.
-	// +kubebuilder:validation:Enum:=layer2; bgp
-	Protocol string `json:"protocol"`
-
-	// A list of IP address ranges over which MetalLB has authority.
-	// You can list multiple ranges in a single pool, they will all share the
-	// same settings. Each range can be either a CIDR prefix, or an explicit
-	// start-end range of IPs.
-	Addresses []string `json:"addresses"`
-
-	// AutoAssign flag used to prevent MetallB from automatic allocation
-	// for a pool.
-	// +optional
-	// +kubebuilder:default:=true
-	AutoAssign *bool `json:"autoAssign,omitempty"`
-
-	// When an IP is allocated from this pool, how should it be
-	// translated into BGP announcements?
-	// +optional
-	BGPAdvertisements []BgpAdvertisement `json:"bgpAdvertisements,omitempty"`
-}
-
-// AddressPoolStatus defines the observed state of AddressPool.
-type AddressPoolStatus struct {
-	// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
-	// Important: Run "make" to regenerate code after modifying this file
-}
-
-// +kubebuilder:object:root=true
-// +kubebuilder:subresource:status
-// +kubebuilder:deprecatedversion:warning="metallb.io v1alpha1 AddressPool is deprecated"
-
-// AddressPool is the Schema for the addresspools API.
-type AddressPool struct {
-	metav1.TypeMeta   `json:",inline"`
-	metav1.ObjectMeta `json:"metadata,omitempty"`
-
-	Spec   AddressPoolSpec   `json:"spec"`
-	Status AddressPoolStatus `json:"status,omitempty"`
-}
-
-// +kubebuilder:object:root=true
-
-// AddressPoolList contains a list of AddressPool.
-type AddressPoolList struct {
-	metav1.TypeMeta `json:",inline"`
-	metav1.ListMeta `json:"metadata,omitempty"`
-	Items           []AddressPool `json:"items"`
-}
-
-func init() {
-	SchemeBuilder.Register(&AddressPool{}, &AddressPoolList{})
-}
diff --git a/api/v1alpha1/groupversion_info.go b/api/v1alpha1/groupversion_info.go
deleted file mode 100644
index 089cc8ea..00000000
--- a/api/v1alpha1/groupversion_info.go
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Package v1alpha1 contains API Schema definitions for the metallb v1alpha1 API group
-// +kubebuilder:object:generate=true
-// +groupName=metallb.io
-package v1alpha1
-
-import (
-	"k8s.io/apimachinery/pkg/runtime/schema"
-	"sigs.k8s.io/controller-runtime/pkg/scheme"
-)
-
-var (
-	// GroupVersion is group version used to register these objects.
-	GroupVersion = schema.GroupVersion{Group: "metallb.io", Version: "v1alpha1"}
-
-	// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
-	SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
-
-	// AddToScheme adds the types in this group-version to the given scheme.
-	AddToScheme = SchemeBuilder.AddToScheme
-)
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
deleted file mode 100644
index 07109b93..00000000
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ /dev/null
@@ -1,148 +0,0 @@
-//go:build !ignore_autogenerated
-// +build !ignore_autogenerated
-
-//SPDX-License-Identifier:Apache-2.0
-
-// Code generated by controller-gen. DO NOT EDIT.
-
-package v1alpha1
-
-import (
-	runtime "k8s.io/apimachinery/pkg/runtime"
-)
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *AddressPool) DeepCopyInto(out *AddressPool) {
-	*out = *in
-	out.TypeMeta = in.TypeMeta
-	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
-	in.Spec.DeepCopyInto(&out.Spec)
-	out.Status = in.Status
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddressPool.
-func (in *AddressPool) DeepCopy() *AddressPool {
-	if in == nil {
-		return nil
-	}
-	out := new(AddressPool)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *AddressPool) DeepCopyObject() runtime.Object {
-	if c := in.DeepCopy(); c != nil {
-		return c
-	}
-	return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *AddressPoolList) DeepCopyInto(out *AddressPoolList) {
-	*out = *in
-	out.TypeMeta = in.TypeMeta
-	in.ListMeta.DeepCopyInto(&out.ListMeta)
-	if in.Items != nil {
-		in, out := &in.Items, &out.Items
-		*out = make([]AddressPool, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddressPoolList.
-func (in *AddressPoolList) DeepCopy() *AddressPoolList {
-	if in == nil {
-		return nil
-	}
-	out := new(AddressPoolList)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *AddressPoolList) DeepCopyObject() runtime.Object {
-	if c := in.DeepCopy(); c != nil {
-		return c
-	}
-	return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *AddressPoolSpec) DeepCopyInto(out *AddressPoolSpec) {
-	*out = *in
-	if in.Addresses != nil {
-		in, out := &in.Addresses, &out.Addresses
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
-	if in.AutoAssign != nil {
-		in, out := &in.AutoAssign, &out.AutoAssign
-		*out = new(bool)
-		**out = **in
-	}
-	if in.BGPAdvertisements != nil {
-		in, out := &in.BGPAdvertisements, &out.BGPAdvertisements
-		*out = make([]BgpAdvertisement, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddressPoolSpec.
-func (in *AddressPoolSpec) DeepCopy() *AddressPoolSpec {
-	if in == nil {
-		return nil
-	}
-	out := new(AddressPoolSpec)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *AddressPoolStatus) DeepCopyInto(out *AddressPoolStatus) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddressPoolStatus.
-func (in *AddressPoolStatus) DeepCopy() *AddressPoolStatus {
-	if in == nil {
-		return nil
-	}
-	out := new(AddressPoolStatus)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *BgpAdvertisement) DeepCopyInto(out *BgpAdvertisement) {
-	*out = *in
-	if in.AggregationLength != nil {
-		in, out := &in.AggregationLength, &out.AggregationLength
-		*out = new(int32)
-		**out = **in
-	}
-	if in.AggregationLengthV6 != nil {
-		in, out := &in.AggregationLengthV6, &out.AggregationLengthV6
-		*out = new(int32)
-		**out = **in
-	}
-	if in.Communities != nil {
-		in, out := &in.Communities, &out.Communities
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BgpAdvertisement.
-func (in *BgpAdvertisement) DeepCopy() *BgpAdvertisement {
-	if in == nil {
-		return nil
-	}
-	out := new(BgpAdvertisement)
-	in.DeepCopyInto(out)
-	return out
-}
diff --git a/api/v1beta1/addresspool_conversion.go b/api/v1beta1/addresspool_conversion.go
deleted file mode 100644
index 03c0b9e2..00000000
--- a/api/v1beta1/addresspool_conversion.go
+++ /dev/null
@@ -1,6 +0,0 @@
-// SPDX-License-Identifier:Apache-2.0
-
-package v1beta1
-
-// Hub marks this type as a conversion hub.
-func (*AddressPool) Hub() {}
diff --git a/api/v1beta1/addresspool_types.go b/api/v1beta1/addresspool_types.go
deleted file mode 100644
index 7e8f6cdc..00000000
--- a/api/v1beta1/addresspool_types.go
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package v1beta1
-
-import (
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-)
-
-type LegacyBgpAdvertisement struct {
-	// The aggregation-length advertisement option lets you “roll up” the /32s into a larger prefix.
-	// +kubebuilder:validation:Minimum=1
-	// +kubebuilder:default:=32
-	// +optional
-	AggregationLength *int32 `json:"aggregationLength,omitempty"`
-
-	// Optional, defaults to 128 (i.e. no aggregation) if not
-	// specified.
-	// +kubebuilder:default:=128
-	// +optional
-	AggregationLengthV6 *int32 `json:"aggregationLengthV6,omitempty"`
-
-	// BGP LOCAL_PREF attribute which is used by BGP best path algorithm,
-	// Path with higher localpref is preferred over one with lower localpref.
-	LocalPref uint32 `json:"localPref,omitempty"`
-
-	// BGP communities to be associated with the given advertisement.
-	Communities []string `json:"communities,omitempty"`
-}
-
-// AddressPoolSpec defines the desired state of AddressPool.
-type AddressPoolSpec struct {
-	// Protocol can be used to select how the announcement is done.
-	// +kubebuilder:validation:Enum:=layer2; bgp
-	Protocol string `json:"protocol"`
-
-	// A list of IP address ranges over which MetalLB has authority.
-	// You can list multiple ranges in a single pool, they will all share the
-	// same settings. Each range can be either a CIDR prefix, or an explicit
-	// start-end range of IPs.
-	Addresses []string `json:"addresses"`
-
-	// AutoAssign flag used to prevent MetallB from automatic allocation
-	// for a pool.
-	// +optional
-	// +kubebuilder:default:=true
-	AutoAssign *bool `json:"autoAssign,omitempty"`
-
-	// Drives how an IP allocated from this pool should
-	// translated into BGP announcements.
-	// +optional
-	BGPAdvertisements []LegacyBgpAdvertisement `json:"bgpAdvertisements,omitempty"`
-}
-
-// AddressPoolStatus defines the observed state of AddressPool.
-type AddressPoolStatus struct {
-	// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
-	// Important: Run "make" to regenerate code after modifying this file
-}
-
-// +kubebuilder:object:root=true
-// +kubebuilder:subresource:status
-// +kubebuilder:storageversion
-// +kubebuilder:deprecatedversion:warning="metallb.io v1beta1 AddressPool is deprecated, consider using IPAddressPool"
-
-// AddressPool represents a pool of IP addresses that can be allocated
-// to LoadBalancer services.
-// AddressPool is deprecated and being replaced by IPAddressPool.
-type AddressPool struct {
-	metav1.TypeMeta   `json:",inline"`
-	metav1.ObjectMeta `json:"metadata,omitempty"`
-
-	Spec   AddressPoolSpec   `json:"spec"`
-	Status AddressPoolStatus `json:"status,omitempty"`
-}
-
-// +kubebuilder:object:root=true
-
-// AddressPoolList contains a list of AddressPool.
-type AddressPoolList struct {
-	metav1.TypeMeta `json:",inline"`
-	metav1.ListMeta `json:"metadata,omitempty"`
-	Items           []AddressPool `json:"items"`
-}
-
-func init() {
-	SchemeBuilder.Register(&AddressPool{}, &AddressPoolList{})
-}
diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go
index c3a31ed7..cd62bab6 100644
--- a/api/v1beta1/zz_generated.deepcopy.go
+++ b/api/v1beta1/zz_generated.deepcopy.go
@@ -11,112 +11,6 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 )
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *AddressPool) DeepCopyInto(out *AddressPool) {
-	*out = *in
-	out.TypeMeta = in.TypeMeta
-	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
-	in.Spec.DeepCopyInto(&out.Spec)
-	out.Status = in.Status
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddressPool.
-func (in *AddressPool) DeepCopy() *AddressPool {
-	if in == nil {
-		return nil
-	}
-	out := new(AddressPool)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *AddressPool) DeepCopyObject() runtime.Object {
-	if c := in.DeepCopy(); c != nil {
-		return c
-	}
-	return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *AddressPoolList) DeepCopyInto(out *AddressPoolList) {
-	*out = *in
-	out.TypeMeta = in.TypeMeta
-	in.ListMeta.DeepCopyInto(&out.ListMeta)
-	if in.Items != nil {
-		in, out := &in.Items, &out.Items
-		*out = make([]AddressPool, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddressPoolList.
-func (in *AddressPoolList) DeepCopy() *AddressPoolList {
-	if in == nil {
-		return nil
-	}
-	out := new(AddressPoolList)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
-func (in *AddressPoolList) DeepCopyObject() runtime.Object {
-	if c := in.DeepCopy(); c != nil {
-		return c
-	}
-	return nil
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *AddressPoolSpec) DeepCopyInto(out *AddressPoolSpec) {
-	*out = *in
-	if in.Addresses != nil {
-		in, out := &in.Addresses, &out.Addresses
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
-	if in.AutoAssign != nil {
-		in, out := &in.AutoAssign, &out.AutoAssign
-		*out = new(bool)
-		**out = **in
-	}
-	if in.BGPAdvertisements != nil {
-		in, out := &in.BGPAdvertisements, &out.BGPAdvertisements
-		*out = make([]LegacyBgpAdvertisement, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddressPoolSpec.
-func (in *AddressPoolSpec) DeepCopy() *AddressPoolSpec {
-	if in == nil {
-		return nil
-	}
-	out := new(AddressPoolSpec)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *AddressPoolStatus) DeepCopyInto(out *AddressPoolStatus) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddressPoolStatus.
-func (in *AddressPoolStatus) DeepCopy() *AddressPoolStatus {
-	if in == nil {
-		return nil
-	}
-	out := new(AddressPoolStatus)
-	in.DeepCopyInto(out)
-	return out
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *BFDProfile) DeepCopyInto(out *BFDProfile) {
 	*out = *in
@@ -646,36 +540,6 @@ func (in *L2AdvertisementStatus) DeepCopy() *L2AdvertisementStatus {
 	return out
 }
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *LegacyBgpAdvertisement) DeepCopyInto(out *LegacyBgpAdvertisement) {
-	*out = *in
-	if in.AggregationLength != nil {
-		in, out := &in.AggregationLength, &out.AggregationLength
-		*out = new(int32)
-		**out = **in
-	}
-	if in.AggregationLengthV6 != nil {
-		in, out := &in.AggregationLengthV6, &out.AggregationLengthV6
-		*out = new(int32)
-		**out = **in
-	}
-	if in.Communities != nil {
-		in, out := &in.Communities, &out.Communities
-		*out = make([]string, len(*in))
-		copy(*out, *in)
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LegacyBgpAdvertisement.
-func (in *LegacyBgpAdvertisement) DeepCopy() *LegacyBgpAdvertisement {
-	if in == nil {
-		return nil
-	}
-	out := new(LegacyBgpAdvertisement)
-	in.DeepCopyInto(out)
-	return out
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *MatchExpression) DeepCopyInto(out *MatchExpression) {
 	*out = *in
diff --git a/internal/config/config.go b/internal/config/config.go
index b2ac6673..66103765 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -36,17 +36,16 @@ import (
 )
 
 type ClusterResources struct {
-	Pools              []metallbv1beta1.IPAddressPool    `json:"ipaddresspools"`
-	Peers              []metallbv1beta2.BGPPeer          `json:"bgppeers"`
-	BFDProfiles        []metallbv1beta1.BFDProfile       `json:"bfdprofiles"`
-	BGPAdvs            []metallbv1beta1.BGPAdvertisement `json:"bgpadvertisements"`
-	L2Advs             []metallbv1beta1.L2Advertisement  `json:"l2advertisements"`
-	LegacyAddressPools []metallbv1beta1.AddressPool      `json:"legacyaddresspools"`
-	Communities        []metallbv1beta1.Community        `json:"communities"`
-	PasswordSecrets    map[string]corev1.Secret          `json:"passwordsecrets"`
-	Nodes              []corev1.Node                     `json:"nodes"`
-	Namespaces         []corev1.Namespace                `json:"namespaces"`
-	BGPExtras          corev1.ConfigMap                  `json:"bgpextras"`
+	Pools           []metallbv1beta1.IPAddressPool    `json:"ipaddresspools"`
+	Peers           []metallbv1beta2.BGPPeer          `json:"bgppeers"`
+	BFDProfiles     []metallbv1beta1.BFDProfile       `json:"bfdprofiles"`
+	BGPAdvs         []metallbv1beta1.BGPAdvertisement `json:"bgpadvertisements"`
+	L2Advs          []metallbv1beta1.L2Advertisement  `json:"l2advertisements"`
+	Communities     []metallbv1beta1.Community        `json:"communities"`
+	PasswordSecrets map[string]corev1.Secret          `json:"passwordsecrets"`
+	Nodes           []corev1.Node                     `json:"nodes"`
+	Namespaces      []corev1.Namespace                `json:"namespaces"`
+	BGPExtras       corev1.ConfigMap                  `json:"bgpextras"`
 }
 
 // Config is a parsed MetalLB configuration.
@@ -333,33 +332,6 @@ func poolsFor(resources ClusterResources) (*Pools, error) {
 		return nil, err
 	}
 
-	for _, p := range resources.LegacyAddressPools {
-		allNodes, err := selectedNodes(resources.Nodes, nil)
-		if err != nil {
-			return nil, err
-		}
-		pool, err := addressPoolFromLegacyCR(p, communities, allNodes)
-		if err != nil {
-			return nil, errors.Wrapf(err, "parsing address pool %s", p.Name)
-		}
-
-		// Check that the pool isn't already defined
-		if pools[p.Name] != nil {
-			return nil, fmt.Errorf("duplicate definition of pool %q", p.Name)
-		}
-
-		// Check that all specified CIDR ranges are non-overlapping.
-		for _, cidr := range pool.CIDR {
-			for _, m := range allCIDRs {
-				if cidrsOverlap(cidr, m) {
-					return nil, fmt.Errorf("CIDR %q in pool %q overlaps with already defined CIDR %q", cidr, p.Name, m)
-				}
-			}
-			allCIDRs = append(allCIDRs, cidr)
-		}
-
-		pools[p.Name] = pool
-	}
 	return &Pools{ByName: pools, ByNamespace: poolsByNamespace(pools),
 		ByServiceSelector: poolsByServiceSelector(pools)}, nil
 }
@@ -611,57 +583,6 @@ func poolsByServiceSelector(pools map[string]*Pool) []string {
 	return poolsByServiceSelector
 }
 
-func addressPoolFromLegacyCR(p metallbv1beta1.AddressPool, bgpCommunities map[string]community.BGPCommunity, allNodes map[string]bool) (*Pool, error) {
-	if p.Name == "" {
-		return nil, errors.New("missing pool name")
-	}
-
-	ret := &Pool{
-		Name:       p.Name,
-		AutoAssign: true,
-	}
-
-	if p.Spec.AutoAssign != nil {
-		ret.AutoAssign = *p.Spec.AutoAssign
-	}
-
-	if len(p.Spec.Addresses) == 0 {
-		return nil, errors.New("pool has no prefixes defined")
-	}
-
-	cidrsPerAddresses := map[string][]*net.IPNet{}
-	for _, cidr := range p.Spec.Addresses {
-		nets, err := ParseCIDR(cidr)
-		if err != nil {
-			return nil, fmt.Errorf("invalid CIDR %q in pool %q: %s", cidr, p.Name, err)
-		}
-		ret.CIDR = append(ret.CIDR, nets...)
-		cidrsPerAddresses[cidr] = nets
-	}
-	switch Proto(p.Spec.Protocol) {
-	case Layer2:
-		if len(p.Spec.BGPAdvertisements) > 0 {
-			return nil, errors.New("cannot have bgp-advertisements configuration element in a layer2 address pool")
-		}
-		ret.L2Advertisements = []*L2Advertisement{{Nodes: allNodes, AllInterfaces: true}}
-	case BGP:
-		ads, err := bgpAdvertisementsFromLegacyCR(p.Spec.BGPAdvertisements, cidrsPerAddresses, bgpCommunities, allNodes)
-		if err != nil {
-			return nil, errors.Wrapf(err, "parsing BGP advertisements")
-		}
-		ret.BGPAdvertisements = ads
-		if len(ads) == 0 { // Fill an empty bgpadvertisement to declare we want to advertise this pool
-			ret.BGPAdvertisements = []*BGPAdvertisement{{}}
-		}
-	case "":
-		return nil, errors.New("address pool is missing the protocol field")
-	default:
-		return nil, fmt.Errorf("unknown protocol %q", p.Spec.Protocol)
-	}
-
-	return ret, nil
-}
-
 func bfdProfileFromCR(p metallbv1beta1.BFDProfile) (*BFDProfile, error) {
 	if p.Name == "" {
 		return nil, fmt.Errorf("missing bfd profile name")
@@ -858,80 +779,6 @@ func bgpAdvertisementFromCR(crdAd metallbv1beta1.BGPAdvertisement, communities m
 	return ad, nil
 }
 
-func bgpAdvertisementsFromLegacyCR(ads []metallbv1beta1.LegacyBgpAdvertisement, cidrsPerAddresses map[string][]*net.IPNet, communities map[string]community.BGPCommunity, allNodes map[string]bool) ([]*BGPAdvertisement, error) {
-	if len(ads) == 0 {
-		return []*BGPAdvertisement{
-			{
-				AggregationLength:   32,
-				AggregationLengthV6: 128,
-				LocalPref:           0,
-				Communities:         map[community.BGPCommunity]bool{},
-				Nodes:               allNodes,
-			},
-		}, nil
-	}
-
-	var ret []*BGPAdvertisement
-	for _, crdAd := range ads {
-		err := validateDuplicate(crdAd.Communities, "community")
-		if err != nil {
-			return nil, err
-		}
-
-		ad := &BGPAdvertisement{
-			AggregationLength:   32,
-			AggregationLengthV6: 128,
-			LocalPref:           0,
-			Communities:         map[community.BGPCommunity]bool{},
-			Nodes:               allNodes,
-		}
-
-		if crdAd.AggregationLength != nil {
-			ad.AggregationLength = int(*crdAd.AggregationLength)
-		}
-		if ad.AggregationLength > 32 {
-			return nil, fmt.Errorf("invalid aggregation length %q for IPv4", ad.AggregationLength)
-		}
-		if crdAd.AggregationLengthV6 != nil {
-			ad.AggregationLengthV6 = int(*crdAd.AggregationLengthV6)
-			if ad.AggregationLengthV6 > 128 {
-				return nil, fmt.Errorf("invalid aggregation length %q for IPv6", ad.AggregationLengthV6)
-			}
-		}
-
-		for addr, cidrs := range cidrsPerAddresses {
-			if len(cidrs) == 0 {
-				continue
-			}
-			maxLength := ad.AggregationLength
-			if cidrs[0].IP.To4() == nil {
-				maxLength = ad.AggregationLengthV6
-			}
-
-			// in case of range format, we may have a set of cidrs associated to a given address.
-			// We reject if none of the cidrs are compatible with the aggregation length.
-			lowest := lowestMask(cidrs)
-			if maxLength < lowest {
-				return nil, fmt.Errorf("invalid aggregation length %d: prefix %d in "+
-					"this pool is more specific than the aggregation length for addresses %s", ad.AggregationLength, lowest, addr)
-			}
-		}
-
-		ad.LocalPref = crdAd.LocalPref
-
-		for _, c := range crdAd.Communities {
-			v, err := getCommunityValue(c, communities)
-			if err != nil {
-				return nil, errors.Wrapf(err, "invalid community %q in BGP advertisement", c)
-			}
-			ad.Communities[v] = true
-		}
-		ret = append(ret, ad)
-	}
-
-	return ret, nil
-}
-
 // getCommunityValue returns the BGPCommunity from the communities map if it exists there. Otherwise, it creates a
 // new BGP community object from the provided communityString.
 func getCommunityValue(communityString string, communities map[string]community.BGPCommunity) (community.BGPCommunity, error) {
diff --git a/internal/config/validation.go b/internal/config/validation.go
index e11af300..dedc5fc5 100644
--- a/internal/config/validation.go
+++ b/internal/config/validation.go
@@ -75,21 +75,6 @@ func findIPv6BGPAdvertisement(c ClusterResources) error {
 // findNonLegacyCommunity returns an error if it can find a non legacy community. If a community string can not be
 // parsed, the string will be ignored.
 func findNonLegacyCommunity(c ClusterResources) error {
-	for _, p := range c.LegacyAddressPools {
-		for _, adv := range p.Spec.BGPAdvertisements {
-			for _, cs := range adv.Communities {
-				c, err := community.New(cs)
-				if err != nil {
-					// Skip aliases.
-					continue
-				}
-				if !community.IsLegacy(c) {
-					return fmt.Errorf("native BGP mode only supports legacy communities, legacy address pool %q "+
-						"has non legacy community %q", p.Name, cs)
-				}
-			}
-		}
-	}
 	for _, adv := range c.BGPAdvs {
 		for _, cs := range adv.Spec.Communities {
 			c, err := community.New(cs)
diff --git a/internal/config/validator.go b/internal/config/validator.go
index a2895495..03ae6ea9 100644
--- a/internal/config/validator.go
+++ b/internal/config/validator.go
@@ -30,13 +30,12 @@ type validator struct {
 
 func (v *validator) Validate(resources ...client.ObjectList) error {
 	clusterResources := ClusterResources{
-		Pools:              make([]metallbv1beta1.IPAddressPool, 0),
-		Peers:              make([]metallbv1beta2.BGPPeer, 0),
-		BFDProfiles:        make([]metallbv1beta1.BFDProfile, 0),
-		BGPAdvs:            make([]metallbv1beta1.BGPAdvertisement, 0),
-		L2Advs:             make([]metallbv1beta1.L2Advertisement, 0),
-		LegacyAddressPools: make([]metallbv1beta1.AddressPool, 0),
-		Communities:        make([]metallbv1beta1.Community, 0),
+		Pools:       make([]metallbv1beta1.IPAddressPool, 0),
+		Peers:       make([]metallbv1beta2.BGPPeer, 0),
+		BFDProfiles: make([]metallbv1beta1.BFDProfile, 0),
+		BGPAdvs:     make([]metallbv1beta1.BGPAdvertisement, 0),
+		L2Advs:      make([]metallbv1beta1.L2Advertisement, 0),
+		Communities: make([]metallbv1beta1.Community, 0),
 	}
 	for _, list := range resources {
 		switch list := list.(type) {
@@ -50,8 +49,6 @@ func (v *validator) Validate(resources ...client.ObjectList) error {
 			clusterResources.BGPAdvs = append(clusterResources.BGPAdvs, list.Items...)
 		case *metallbv1beta1.L2AdvertisementList:
 			clusterResources.L2Advs = append(clusterResources.L2Advs, list.Items...)
-		case *metallbv1beta1.AddressPoolList:
-			clusterResources.LegacyAddressPools = append(clusterResources.LegacyAddressPools, list.Items...)
 		case *metallbv1beta1.CommunityList:
 			clusterResources.Communities = append(clusterResources.Communities, list.Items...)
 		case *v1.NodeList:
@@ -84,17 +81,5 @@ func resetTransientErrorsFields(clusterResources ClusterResources) ClusterResour
 		}
 		clusterResources.BGPAdvs[i].Spec.Communities = communities
 	}
-	for i, legacyAddrPool := range clusterResources.LegacyAddressPools {
-		for j, bgpAdv := range legacyAddrPool.Spec.BGPAdvertisements {
-			var communities []string
-			for k := range bgpAdv.Communities {
-				// We want to pass only communities that are potentially explicit values.
-				if strings.Contains(bgpAdv.Communities[k], ":") {
-					communities = append(communities, bgpAdv.Communities[k])
-				}
-			}
-			clusterResources.LegacyAddressPools[i].Spec.BGPAdvertisements[j].Communities = communities
-		}
-	}
 	return clusterResources
 }
diff --git a/internal/k8s/controllers/config_controller.go b/internal/k8s/controllers/config_controller.go
index 2be85d94..4f741273 100644
--- a/internal/k8s/controllers/config_controller.go
+++ b/internal/k8s/controllers/config_controller.go
@@ -59,12 +59,6 @@ var requestHandler = func(r *ConfigReconciler, ctx context.Context, req ctrl.Req
 	defer level.Info(r.Logger).Log("controller", "ConfigReconciler", "end reconcile", req.NamespacedName.String())
 	updates.Inc()
 
-	var addressPools metallbv1beta1.AddressPoolList
-	if err := r.List(ctx, &addressPools, client.InNamespace(r.Namespace)); err != nil {
-		level.Error(r.Logger).Log("controller", "ConfigReconciler", "message", "failed to get addresspools", "error", err)
-		return ctrl.Result{}, err
-	}
-
 	var ipAddressPools metallbv1beta1.IPAddressPoolList
 	if err := r.List(ctx, &ipAddressPools, client.InNamespace(r.Namespace)); err != nil {
 		level.Error(r.Logger).Log("controller", "ConfigReconciler", "error", "failed to get ipaddresspools", "error", err)
@@ -126,17 +120,16 @@ var requestHandler = func(r *ConfigReconciler, ctx context.Context, req ctrl.Req
 	}
 
 	resources := config.ClusterResources{
-		Pools:              ipAddressPools.Items,
-		Peers:              bgpPeers.Items,
-		BFDProfiles:        bfdProfiles.Items,
-		L2Advs:             l2Advertisements.Items,
-		BGPAdvs:            bgpAdvertisements.Items,
-		LegacyAddressPools: addressPools.Items,
-		Communities:        communities.Items,
-		PasswordSecrets:    secrets,
-		Nodes:              nodes.Items,
-		Namespaces:         namespaces.Items,
-		BGPExtras:          extrasMap,
+		Pools:           ipAddressPools.Items,
+		Peers:           bgpPeers.Items,
+		BFDProfiles:     bfdProfiles.Items,
+		L2Advs:          l2Advertisements.Items,
+		BGPAdvs:         bgpAdvertisements.Items,
+		Communities:     communities.Items,
+		PasswordSecrets: secrets,
+		Nodes:           nodes.Items,
+		Namespaces:      namespaces.Items,
+		BGPExtras:       extrasMap,
 	}
 
 	level.Debug(r.Logger).Log("controller", "ConfigReconciler", "metallb CRs and Secrets", dumpClusterResources(&resources))
@@ -199,7 +192,6 @@ func (r *ConfigReconciler) SetupWithManager(mgr ctrl.Manager) error {
 		Watches(&metallbv1beta1.BGPAdvertisement{}, &handler.EnqueueRequestForObject{}).
 		Watches(&metallbv1beta1.L2Advertisement{}, &handler.EnqueueRequestForObject{}).
 		Watches(&metallbv1beta1.BFDProfile{}, &handler.EnqueueRequestForObject{}).
-		Watches(&metallbv1beta1.AddressPool{}, &handler.EnqueueRequestForObject{}).
 		Watches(&metallbv1beta1.Community{}, &handler.EnqueueRequestForObject{}).
 		Watches(&corev1.Secret{}, &handler.EnqueueRequestForObject{}).
 		Watches(&corev1.Namespace{}, &handler.EnqueueRequestForObject{}).
diff --git a/internal/k8s/controllers/config_conversion.go b/internal/k8s/controllers/config_conversion.go
index fc36e948..196a21f7 100644
--- a/internal/k8s/controllers/config_conversion.go
+++ b/internal/k8s/controllers/config_conversion.go
@@ -10,17 +10,16 @@ import (
 
 func toConfig(fromK8s config.ClusterResources, validate config.Validate) (*config.Config, error) {
 	resources := config.ClusterResources{
-		Pools:              sortedCopy(fromK8s.Pools),
-		Peers:              sortedCopy(fromK8s.Peers),
-		BFDProfiles:        sortedCopy(fromK8s.BFDProfiles),
-		L2Advs:             sortedCopy(fromK8s.L2Advs),
-		BGPAdvs:            sortedCopy(fromK8s.BGPAdvs),
-		LegacyAddressPools: sortedCopy(fromK8s.LegacyAddressPools),
-		Communities:        sortedCopy(fromK8s.Communities),
-		PasswordSecrets:    fromK8s.PasswordSecrets,
-		Nodes:              sortedCopy(fromK8s.Nodes),
-		Namespaces:         sortedCopy(fromK8s.Namespaces),
-		BGPExtras:          fromK8s.BGPExtras,
+		Pools:           sortedCopy(fromK8s.Pools),
+		Peers:           sortedCopy(fromK8s.Peers),
+		BFDProfiles:     sortedCopy(fromK8s.BFDProfiles),
+		L2Advs:          sortedCopy(fromK8s.L2Advs),
+		BGPAdvs:         sortedCopy(fromK8s.BGPAdvs),
+		Communities:     sortedCopy(fromK8s.Communities),
+		PasswordSecrets: fromK8s.PasswordSecrets,
+		Nodes:           sortedCopy(fromK8s.Nodes),
+		Namespaces:      sortedCopy(fromK8s.Namespaces),
+		BGPExtras:       fromK8s.BGPExtras,
 	}
 
 	cfg, err := config.For(resources, validate)
diff --git a/internal/k8s/controllers/dump.go b/internal/k8s/controllers/dump.go
index 9311381c..41e1b00e 100644
--- a/internal/k8s/controllers/dump.go
+++ b/internal/k8s/controllers/dump.go
@@ -13,14 +13,13 @@ import (
 
 func dumpClusterResources(c *config.ClusterResources) string {
 	withNoSecret := config.ClusterResources{
-		Pools:              c.Pools,
-		Peers:              sanitizeBGPPeer(c.Peers...),
-		BFDProfiles:        c.BFDProfiles,
-		L2Advs:             c.L2Advs,
-		BGPAdvs:            c.BGPAdvs,
-		LegacyAddressPools: c.LegacyAddressPools,
-		Communities:        c.Communities,
-		BGPExtras:          c.BGPExtras,
+		Pools:       c.Pools,
+		Peers:       sanitizeBGPPeer(c.Peers...),
+		BFDProfiles: c.BFDProfiles,
+		L2Advs:      c.L2Advs,
+		BGPAdvs:     c.BGPAdvs,
+		Communities: c.Communities,
+		BGPExtras:   c.BGPExtras,
 	}
 	withNoSecret.PasswordSecrets = make(map[string]corev1.Secret)
 	for k, s := range c.PasswordSecrets {
diff --git a/internal/k8s/controllers/pool_controller.go b/internal/k8s/controllers/pool_controller.go
index 0170dd90..d072c00d 100644
--- a/internal/k8s/controllers/pool_controller.go
+++ b/internal/k8s/controllers/pool_controller.go
@@ -49,12 +49,6 @@ func (r *PoolReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.
 	defer level.Info(r.Logger).Log("controller", "PoolReconciler", "end reconcile", req.NamespacedName.String())
 	updates.Inc()
 
-	var addressPools metallbv1beta1.AddressPoolList
-	if err := r.List(ctx, &addressPools, client.InNamespace(r.Namespace)); err != nil {
-		level.Error(r.Logger).Log("controller", "PoolReconciler", "message", "failed to get addresspools", "error", err)
-		return ctrl.Result{}, err
-	}
-
 	var ipAddressPools metallbv1beta1.IPAddressPoolList
 	if err := r.List(ctx, &ipAddressPools, client.InNamespace(r.Namespace)); err != nil {
 		level.Error(r.Logger).Log("controller", "PoolReconciler", "message", "failed to get ipaddresspools", "error", err)
@@ -74,10 +68,9 @@ func (r *PoolReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.
 	}
 
 	resources := config.ClusterResources{
-		Pools:              ipAddressPools.Items,
-		LegacyAddressPools: addressPools.Items,
-		Communities:        communities.Items,
-		Namespaces:         namespaces.Items,
+		Pools:       ipAddressPools.Items,
+		Communities: communities.Items,
+		Namespaces:  namespaces.Items,
 	}
 
 	level.Debug(r.Logger).Log("controller", "PoolReconciler", "metallb CRs", dumpClusterResources(&resources))
@@ -128,7 +121,6 @@ func (r *PoolReconciler) SetupWithManager(mgr ctrl.Manager) error {
 	}
 	return ctrl.NewControllerManagedBy(mgr).
 		For(&metallbv1beta1.IPAddressPool{}).
-		Watches(&metallbv1beta1.AddressPool{}, &handler.EnqueueRequestForObject{}).
 		Watches(&metallbv1beta1.Community{}, &handler.EnqueueRequestForObject{}).
 		Watches(&corev1.Namespace{}, &handler.EnqueueRequestForObject{}).
 		WithEventFilter(p).
diff --git a/internal/k8s/k8s.go b/internal/k8s/k8s.go
index 0a21352d..7cecb5c7 100644
--- a/internal/k8s/k8s.go
+++ b/internal/k8s/k8s.go
@@ -21,7 +21,6 @@ import (
 	metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
 	"sigs.k8s.io/controller-runtime/pkg/webhook"
 
-	metallbv1alpha1 "go.universe.tf/metallb/api/v1alpha1"
 	metallbv1beta1 "go.universe.tf/metallb/api/v1beta1"
 	metallbv1beta2 "go.universe.tf/metallb/api/v1beta2"
 
@@ -69,7 +68,6 @@ var (
 func init() {
 	utilruntime.Must(clientgoscheme.AddToScheme(scheme))
 
-	utilruntime.Must(metallbv1alpha1.AddToScheme(scheme))
 	utilruntime.Must(metallbv1beta1.AddToScheme(scheme))
 	utilruntime.Must(metallbv1beta2.AddToScheme(scheme))
 
@@ -133,7 +131,6 @@ func New(cfg *Config) (*Client, error) {
 	}
 
 	objectsPerNamespace := map[client.Object]cache.ByObject{
-		&metallbv1beta1.AddressPool{}:      namespaceSelector,
 		&metallbv1beta1.BFDProfile{}:       namespaceSelector,
 		&metallbv1beta1.BGPAdvertisement{}: namespaceSelector,
 		&metallbv1beta1.BGPPeer{}:          namespaceSelector,
diff --git a/internal/k8s/webhook.go b/internal/k8s/webhook.go
index 37963418..5301a208 100644
--- a/internal/k8s/webhook.go
+++ b/internal/k8s/webhook.go
@@ -66,11 +66,6 @@ func enableWebhook(mgr manager.Manager, validate config.Validate, namespace stri
 	webhookv1beta1.Validator = config.NewValidator(validate)
 	webhookv1beta2.Validator = config.NewValidator(validate)
 
-	if err := (&webhookv1beta1.AddressPoolValidator{}).SetupWebhookWithManager(mgr); err != nil {
-		level.Error(logger).Log("op", "startup", "error", err, "msg", "unable to create webhook", "webhook", "AddressPool")
-		return err
-	}
-
 	if err := (&webhookv1beta1.IPAddressPoolValidator{}).SetupWebhookWithManager(mgr); err != nil {
 		level.Error(logger).Log("op", "startup", "error", err, "msg", "unable to create webhook", "webhook", "IPAddressPool")
 		return err
diff --git a/internal/k8s/webhooks/webhookv1beta1/addresspool_webhook.go b/internal/k8s/webhooks/webhookv1beta1/addresspool_webhook.go
deleted file mode 100644
index f047259a..00000000
--- a/internal/k8s/webhooks/webhookv1beta1/addresspool_webhook.go
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
-
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package webhookv1beta1
-
-import (
-	"context"
-	"fmt"
-	"net/http"
-
-	"github.com/go-kit/log/level"
-	"github.com/pkg/errors"
-	"go.universe.tf/metallb/api/v1beta1"
-	v1 "k8s.io/api/admission/v1"
-	ctrl "sigs.k8s.io/controller-runtime"
-	"sigs.k8s.io/controller-runtime/pkg/client"
-	"sigs.k8s.io/controller-runtime/pkg/webhook"
-	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
-)
-
-const addressPoolWebhookPath = "/validate-metallb-io-v1beta1-addresspool"
-
-func (v *AddressPoolValidator) SetupWebhookWithManager(mgr ctrl.Manager) error {
-	v.client = mgr.GetClient()
-	v.decoder = admission.NewDecoder(mgr.GetScheme())
-
-	mgr.GetWebhookServer().Register(
-		addressPoolWebhookPath,
-		&webhook.Admission{Handler: v})
-
-	return nil
-}
-
-// +kubebuilder:webhook:verbs=create;update,path=/validate-metallb-io-v1beta1-addresspool,mutating=false,failurePolicy=fail,groups=metallb.io,resources=addresspools,versions=v1beta1,name=addresspoolvalidationwebhook.metallb.io,sideEffects=None,admissionReviewVersions=v1
-type AddressPoolValidator struct {
-	ClusterResourceNamespace string
-
-	client  client.Client
-	decoder *admission.Decoder
-}
-
-// Handle handled incoming admission requests for AddressPool objects.
-func (v *AddressPoolValidator) Handle(ctx context.Context, req admission.Request) (resp admission.Response) {
-	var pool v1beta1.AddressPool
-	var oldPool v1beta1.AddressPool
-	if req.Operation == v1.Delete {
-		if err := v.decoder.DecodeRaw(req.OldObject, &pool); err != nil {
-			return admission.Errored(http.StatusBadRequest, err)
-		}
-	} else {
-		if err := v.decoder.Decode(req, &pool); err != nil {
-			return admission.Errored(http.StatusBadRequest, err)
-		}
-		if req.OldObject.Size() > 0 {
-			if err := v.decoder.DecodeRaw(req.OldObject, &oldPool); err != nil {
-				return admission.Errored(http.StatusBadRequest, err)
-			}
-		}
-	}
-
-	switch req.Operation {
-	case v1.Create:
-		err := validateAddressPoolCreate(&pool)
-		if err != nil {
-			return admission.Denied(err.Error())
-		}
-	case v1.Update:
-		err := validateAddressPoolUpdate(&pool, &oldPool)
-		if err != nil {
-			return admission.Denied(err.Error())
-		}
-	case v1.Delete:
-		err := validateAddressPoolDelete(&pool)
-		if err != nil {
-			return admission.Denied(err.Error())
-		}
-	}
-	return admission.Allowed("")
-}
-
-// validateAddressPoolCreate implements webhook.Validator so a webhook will be registered for AddressPool.
-func validateAddressPoolCreate(addressPool *v1beta1.AddressPool) error {
-	level.Debug(Logger).Log("webhook", "addressPool", "action", "create", "name", addressPool.Name, "namespace", addressPool.Namespace)
-
-	if addressPool.Namespace != MetalLBNamespace {
-		return fmt.Errorf("resource must be created in %s namespace", MetalLBNamespace)
-	}
-
-	existingAddressPoolList, err := getExistingAddressPools()
-	if err != nil {
-		return err
-	}
-
-	existingIPAddressPoolList, err := getExistingIPAddressPools()
-	if err != nil {
-		return err
-	}
-	addressPoolList := listWithUpdate(existingAddressPoolList, addressPool)
-	err = Validator.Validate(addressPoolList, existingIPAddressPoolList)
-	if err != nil {
-		level.Error(Logger).Log("webhook", "addressPool", "action", "create", "name", addressPool.Name, "namespace", addressPool.Namespace, "error", err)
-		return err
-	}
-	return nil
-}
-
-// validateAddressPoolUpdate implements webhook.Validator so a webhook will be registered for AddressPool.
-func validateAddressPoolUpdate(addressPool *v1beta1.AddressPool, _ *v1beta1.AddressPool) error {
-	level.Debug(Logger).Log("webhook", "addressPool", "action", "update", "name", addressPool.Name, "namespace", addressPool.Namespace)
-
-	existingAddressPoolList, err := getExistingAddressPools()
-	if err != nil {
-		return err
-	}
-
-	existingIPAddressPoolList, err := getExistingIPAddressPools()
-	if err != nil {
-		return err
-	}
-	addressPoolList := listWithUpdate(existingAddressPoolList, addressPool)
-	err = Validator.Validate(addressPoolList, existingIPAddressPoolList)
-	if err != nil {
-		level.Error(Logger).Log("webhook", "addressPool", "action", "update", "name", addressPool.Name, "namespace", addressPool.Namespace, "error", err)
-		return err
-	}
-	return nil
-}
-
-// validateAddressPoolDelete implements webhook.Validator so a webhook will be registered for AddressPool.
-func validateAddressPoolDelete(addressPool *v1beta1.AddressPool) error {
-	return nil
-}
-
-var getExistingAddressPools = func() (*v1beta1.AddressPoolList, error) {
-	existingAddressPoolList := &v1beta1.AddressPoolList{}
-	err := WebhookClient.List(context.Background(), existingAddressPoolList, &client.ListOptions{Namespace: MetalLBNamespace})
-	if err != nil {
-		return nil, errors.Wrapf(err, "Failed to get existing AddressPool objects")
-	}
-	return existingAddressPoolList, nil
-}
-
-func listWithUpdate(existing *v1beta1.AddressPoolList, toAdd *v1beta1.AddressPool) *v1beta1.AddressPoolList {
-	res := existing.DeepCopy()
-	for i, item := range res.Items { // We override the element with the fresh copy
-		if item.Name == toAdd.Name {
-			res.Items[i] = *toAdd.DeepCopy()
-			return res
-		}
-	}
-	res.Items = append(res.Items, *toAdd.DeepCopy())
-	return res
-}
diff --git a/internal/k8s/webhooks/webhookv1beta1/bgpadvertisement_webhook.go b/internal/k8s/webhooks/webhookv1beta1/bgpadvertisement_webhook.go
index 15d9ecbd..ab4c97c2 100644
--- a/internal/k8s/webhooks/webhookv1beta1/bgpadvertisement_webhook.go
+++ b/internal/k8s/webhooks/webhookv1beta1/bgpadvertisement_webhook.go
@@ -104,11 +104,6 @@ func validateBGPAdvCreate(bgpAdv *v1beta1.BGPAdvertisement) error {
 		return err
 	}
 
-	addressPools, err := getExistingAddressPools()
-	if err != nil {
-		return err
-	}
-
 	ipAddressPools, err := getExistingIPAddressPools()
 	if err != nil {
 		return err
@@ -120,7 +115,7 @@ func validateBGPAdvCreate(bgpAdv *v1beta1.BGPAdvertisement) error {
 	}
 
 	toValidate := bgpAdvListWithUpdate(existingBGPAdvList, bgpAdv)
-	err = Validator.Validate(toValidate, addressPools, ipAddressPools, nodes)
+	err = Validator.Validate(toValidate, ipAddressPools, nodes)
 	if err != nil {
 		level.Error(Logger).Log("webhook", "bgpadvertisement", "action", "create", "name", bgpAdv.Name, "namespace", bgpAdv.Namespace, "error", err)
 		return err
@@ -137,11 +132,6 @@ func validateBGPAdvUpdate(bgpAdv *v1beta1.BGPAdvertisement, _ *v1beta1.BGPAdvert
 		return err
 	}
 
-	addressPools, err := getExistingAddressPools()
-	if err != nil {
-		return err
-	}
-
 	ipAddressPools, err := getExistingIPAddressPools()
 	if err != nil {
 		return err
@@ -153,7 +143,7 @@ func validateBGPAdvUpdate(bgpAdv *v1beta1.BGPAdvertisement, _ *v1beta1.BGPAdvert
 	}
 
 	toValidate := bgpAdvListWithUpdate(bgpAdvs, bgpAdv)
-	err = Validator.Validate(toValidate, addressPools, ipAddressPools, nodes)
+	err = Validator.Validate(toValidate, ipAddressPools, nodes)
 	if err != nil {
 		level.Error(Logger).Log("webhook", "bgpadvertisement", "action", "create", "name", bgpAdv.Name, "namespace", bgpAdv.Namespace, "error", err)
 		return err
diff --git a/internal/k8s/webhooks/webhookv1beta1/ipaddresspool_webhook.go b/internal/k8s/webhooks/webhookv1beta1/ipaddresspool_webhook.go
index 3c3f87bc..26330777 100644
--- a/internal/k8s/webhooks/webhookv1beta1/ipaddresspool_webhook.go
+++ b/internal/k8s/webhooks/webhookv1beta1/ipaddresspool_webhook.go
@@ -103,12 +103,8 @@ func validateIPAddressPoolCreate(ipAddress *v1beta1.IPAddressPool) error {
 		return err
 	}
 
-	existingAddressPoolList, err := getExistingAddressPools()
-	if err != nil {
-		return err
-	}
 	toValidate := ipAddressListWithUpdate(existingIPAddressPoolList, ipAddress)
-	err = Validator.Validate(existingAddressPoolList, toValidate)
+	err = Validator.Validate(toValidate)
 	if err != nil {
 		level.Error(Logger).Log("webhook", "ipAddress", "action", "create", "name", ipAddress.Name, "namespace", ipAddress.Namespace, "error", err)
 		return err
@@ -119,10 +115,6 @@ func validateIPAddressPoolCreate(ipAddress *v1beta1.IPAddressPool) error {
 // validateIPAddressPoolUpdate implements webhook.Validator so a webhook will be registered for IPAddressPool.
 func validateIPAddressPoolUpdate(ipAddress *v1beta1.IPAddressPool, _ *v1beta1.IPAddressPool) error {
 	level.Debug(Logger).Log("webhook", "ipaddresspool", "action", "update", "name", ipAddress.Name, "namespace", ipAddress.Namespace)
-	existingAddressPoolList, err := getExistingAddressPools()
-	if err != nil {
-		return err
-	}
 
 	existingIPAddressPoolList, err := getExistingIPAddressPools()
 	if err != nil {
@@ -130,7 +122,7 @@ func validateIPAddressPoolUpdate(ipAddress *v1beta1.IPAddressPool, _ *v1beta1.IP
 	}
 
 	toValidate := ipAddressListWithUpdate(existingIPAddressPoolList, ipAddress)
-	err = Validator.Validate(existingAddressPoolList, toValidate)
+	err = Validator.Validate(toValidate)
 	if err != nil {
 		level.Error(Logger).Log("webhook", "ipAddress", "action", "update", "name", ipAddress.Name, "namespace", ipAddress.Namespace, "error", err)
 		return err
diff --git a/internal/k8s/webhooks/webhookv1beta1/l2advertisement_webhook.go b/internal/k8s/webhooks/webhookv1beta1/l2advertisement_webhook.go
index 44bbf9e3..c68e955b 100644
--- a/internal/k8s/webhooks/webhookv1beta1/l2advertisement_webhook.go
+++ b/internal/k8s/webhooks/webhookv1beta1/l2advertisement_webhook.go
@@ -104,18 +104,13 @@ func validateL2AdvCreate(l2Adv *v1beta1.L2Advertisement) error {
 		return err
 	}
 
-	addressPools, err := getExistingAddressPools()
-	if err != nil {
-		return err
-	}
-
 	ipAddressPools, err := getExistingIPAddressPools()
 	if err != nil {
 		return err
 	}
 
 	toValidate := l2AdvListWithUpdate(existingL2AdvList, l2Adv)
-	err = Validator.Validate(toValidate, addressPools, ipAddressPools)
+	err = Validator.Validate(toValidate, ipAddressPools)
 	if err != nil {
 		level.Error(Logger).Log("webhook", "v1beta1.L2Advertisement", "action", "create", "name", l2Adv.Name, "namespace", l2Adv.Namespace, "error", err)
 		return err
@@ -132,18 +127,13 @@ func validateL2AdvUpdate(l2Adv *v1beta1.L2Advertisement, _ *v1beta1.L2Advertisem
 		return err
 	}
 
-	addressPools, err := getExistingAddressPools()
-	if err != nil {
-		return err
-	}
-
 	ipAddressPools, err := getExistingIPAddressPools()
 	if err != nil {
 		return err
 	}
 
 	toValidate := l2AdvListWithUpdate(l2Advs, l2Adv)
-	err = Validator.Validate(toValidate, addressPools, ipAddressPools)
+	err = Validator.Validate(toValidate, ipAddressPools)
 	if err != nil {
 		level.Error(Logger).Log("webhook", "v1beta1.L2Advertisement", "action", "create", "name", l2Adv.Name, "namespace", l2Adv.Namespace, "error", err)
 		return err
diff --git a/website/content/release-notes/_index.md b/website/content/release-notes/_index.md
index 474a6f2b..a48fcf61 100644
--- a/website/content/release-notes/_index.md
+++ b/website/content/release-notes/_index.md
@@ -5,6 +5,10 @@ weight: 8
 
 ## Next release
 
+- Remove support for the legacy AddressPool API in favor of IPAddressPools.
+Being deprecated for a while we finally stop handling the legacy API and remove it,
+IPs can now be allocated to LoadBalancer Services only via IPAddressPool resources. ([PR 2252](https://github.com/metallb/metallb/pull/2252))
+
 Chores:
 
 - Enforce adding a release notes entry on each PR ([PR 2191](https://github.com/metallb/metallb/pull/2191))
@@ -21,7 +25,6 @@ Chores:
 - Dev-env: Override GOBIN for inv dev-env ([PR 2219](https://github.com/metallb/metallb/pull/2219))
 - Metrics: add ipv4/6 addresses_in_use_total and addresses_total ([PR 2151](https://github.com/metallb/metallb/pull/2151))
 - Squash the prefixes in FRR mode, avoiding duplicate prefixes in the FRR configuration ([PR 2234](https://github.com/metallb/metallb/pull/2234))
-
 - BGP: move the matching peer logic one level up ([PR 2233](https://github.com/metallb/metallb/pull/2233))
 
 ## Version 0.13.12


Test patch:
diff --git a/api/v1alpha1/addresspool_conversion_test.go b/api/v1alpha1/addresspool_conversion_test.go
deleted file mode 100644
index 58068097..00000000
--- a/api/v1alpha1/addresspool_conversion_test.go
+++ /dev/null
@@ -1,136 +0,0 @@
-// SPDX-License-Identifier:Apache-2.0
-
-package v1alpha1
-
-import (
-	"reflect"
-	"testing"
-
-	"go.universe.tf/metallb/api/v1beta1"
-	"go.universe.tf/metallb/internal/pointer"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-)
-
-const (
-	MetalLBTestNameSpace = "metallb-test-namespace"
-)
-
-func TestValidateAddressPoolConvertTo(t *testing.T) {
-	var err error
-	var resAddressPool v1beta1.AddressPool
-
-	convertAddressPool := AddressPool{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      "test-addresspool",
-			Namespace: MetalLBTestNameSpace,
-		},
-		Spec: AddressPoolSpec{
-			Addresses: []string{
-				"1.1.1.1-1.1.1.100",
-			},
-
-			Protocol:   "bgp",
-			AutoAssign: pointer.BoolPtr(false),
-			BGPAdvertisements: []BgpAdvertisement{
-				{
-					AggregationLength:   pointer.Int32Ptr(32),
-					AggregationLengthV6: pointer.Int32Ptr(128),
-					LocalPref:           uint32(100),
-					Communities:         []string{"1234"},
-				},
-			},
-		},
-	}
-
-	expectedAddressPool := v1beta1.AddressPool{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      "test-addresspool",
-			Namespace: MetalLBTestNameSpace,
-		},
-		Spec: v1beta1.AddressPoolSpec{
-			Addresses: []string{
-				"1.1.1.1-1.1.1.100",
-			},
-
-			Protocol:   "bgp",
-			AutoAssign: pointer.BoolPtr(false),
-			BGPAdvertisements: []v1beta1.LegacyBgpAdvertisement{
-				{
-					AggregationLength:   pointer.Int32Ptr(32),
-					AggregationLengthV6: pointer.Int32Ptr(128),
-					LocalPref:           uint32(100),
-					Communities:         []string{"1234"},
-				},
-			},
-		},
-	}
-
-	err = convertAddressPool.ConvertTo(&resAddressPool)
-	if err != nil {
-		t.Fatalf("failed converting AddressPool to v1beta1 version: %s", err)
-	}
-
-	if !reflect.DeepEqual(resAddressPool, expectedAddressPool) {
-		t.Fatalf("expected AddressPool different than converted: %s", err)
-	}
-}
-
-func TestValidateAddressPoolConvertFrom(t *testing.T) {
-	var err error
-	var resAddressPool AddressPool
-
-	convertAddressPool := v1beta1.AddressPool{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      "test-addresspool",
-			Namespace: MetalLBTestNameSpace,
-		},
-		Spec: v1beta1.AddressPoolSpec{
-			Addresses: []string{
-				"1.1.1.1-1.1.1.100",
-			},
-
-			Protocol:   "bgp",
-			AutoAssign: pointer.BoolPtr(false),
-			BGPAdvertisements: []v1beta1.LegacyBgpAdvertisement{
-				{
-					AggregationLength:   pointer.Int32Ptr(32),
-					AggregationLengthV6: pointer.Int32Ptr(128),
-					LocalPref:           uint32(100),
-					Communities:         []string{"1234"},
-				},
-			},
-		},
-	}
-
-	expectedAddressPool := AddressPool{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      "test-addresspool",
-			Namespace: MetalLBTestNameSpace,
-		},
-		Spec: AddressPoolSpec{
-			Addresses: []string{
-				"1.1.1.1-1.1.1.100",
-			},
-
-			Protocol:   "bgp",
-			AutoAssign: pointer.BoolPtr(false),
-			BGPAdvertisements: []BgpAdvertisement{
-				{
-					AggregationLength:   pointer.Int32Ptr(32),
-					AggregationLengthV6: pointer.Int32Ptr(128),
-					LocalPref:           uint32(100),
-					Communities:         []string{"1234"},
-				},
-			},
-		},
-	}
-
-	err = resAddressPool.ConvertFrom(&convertAddressPool)
-	if err != nil {
-		t.Fatalf("failed converting v1beta1 AddressPool: %s", err)
-	}
-
-	if !reflect.DeepEqual(resAddressPool, expectedAddressPool) {
-		t.Fatalf("expected AddressPool different than converted: %s", err)
-	}
-}
diff --git a/e2etest/bgptests/bgp.go b/e2etest/bgptests/bgp.go
index 05766287..f541c8ce 100644
--- a/e2etest/bgptests/bgp.go
+++ b/e2etest/bgptests/bgp.go
@@ -693,7 +693,7 @@ var _ = ginkgo.Describe("BGP", func() {
 			ginkgo.Entry("IPV6", ipfamily.IPv6))
 
 		ginkgo.DescribeTable("configure bgp advertisement and verify it gets propagated",
-			func(rangeWithAdvertisement string, rangeWithoutAdvertisement string, advertisement metallbv1beta1.BGPAdvertisement, legacy bool,
+			func(rangeWithAdvertisement string, rangeWithoutAdvertisement string, advertisement metallbv1beta1.BGPAdvertisement,
 				ipFamily ipfamily.Family, communities []metallbv1beta1.Community) {
 				emptyAdvertisement := metallbv1beta1.BGPAdvertisement{
 					ObjectMeta: metav1.ObjectMeta{
@@ -727,16 +727,8 @@ var _ = ginkgo.Describe("BGP", func() {
 					Communities: communities,
 				}
 
-				if !legacy {
-					resources.Pools = []metallbv1beta1.IPAddressPool{poolWithAdvertisement, poolWithoutAdvertisement}
-					resources.BGPAdvs = []metallbv1beta1.BGPAdvertisement{emptyAdvertisement, advertisement}
-				} else {
-					resources.LegacyAddressPools = make([]metallbv1beta1.AddressPool, 0)
-					resources.LegacyAddressPools = []metallbv1beta1.AddressPool{
-						config.IPAddressPoolToLegacy(poolWithAdvertisement, config.BGP, []metallbv1beta1.BGPAdvertisement{advertisement}),
-						config.IPAddressPoolToLegacy(poolWithoutAdvertisement, config.BGP, []metallbv1beta1.BGPAdvertisement{}),
-					}
-				}
+				resources.Pools = []metallbv1beta1.IPAddressPool{poolWithAdvertisement, poolWithoutAdvertisement}
+				resources.BGPAdvs = []metallbv1beta1.BGPAdvertisement{emptyAdvertisement, advertisement}
 
 				for _, c := range FRRContainers {
 					err := frrcontainer.PairWithNodes(cs, c, ipFamily)
@@ -845,7 +837,6 @@ var _ = ginkgo.Describe("BGP", func() {
 						IPAddressPools: []string{"bgp-with-advertisement"},
 					},
 				},
-				false,
 				ipfamily.IPv4,
 				[]metallbv1beta1.Community{}),
 			ginkgo.Entry("FRR - IPV4 - large community and localpref",
@@ -859,7 +850,6 @@ var _ = ginkgo.Describe("BGP", func() {
 						IPAddressPools: []string{"bgp-with-advertisement"},
 					},
 				},
-				false,
 				ipfamily.IPv4,
 				[]metallbv1beta1.Community{}),
 			ginkgo.Entry("IPV4 - localpref",
@@ -872,7 +862,6 @@ var _ = ginkgo.Describe("BGP", func() {
 						IPAddressPools: []string{"bgp-with-advertisement"},
 					},
 				},
-				false,
 				ipfamily.IPv4,
 				[]metallbv1beta1.Community{}),
 			ginkgo.Entry("IPV4 - community",
@@ -885,7 +874,6 @@ var _ = ginkgo.Describe("BGP", func() {
 						IPAddressPools: []string{"bgp-with-advertisement"},
 					},
 				},
-				false,
 				ipfamily.IPv4,
 				[]metallbv1beta1.Community{}),
 			ginkgo.Entry("IPV4 - community from CRD",
@@ -899,49 +887,8 @@ var _ = ginkgo.Describe("BGP", func() {
 						IPAddressPools: []string{"bgp-with-advertisement"},
 					},
 				},
-				false,
 				ipfamily.IPv4,
 				[]metallbv1beta1.Community{noAdvCommunity}),
-			ginkgo.Entry("IPV4 - community and localpref - legacy",
-				"192.168.10.0/24",
-				"192.168.16.0/24",
-				metallbv1beta1.BGPAdvertisement{
-					ObjectMeta: metav1.ObjectMeta{Name: "advertisement"},
-					Spec: metallbv1beta1.BGPAdvertisementSpec{
-						Communities:    []string{CommunityNoAdv},
-						LocalPref:      50,
-						IPAddressPools: []string{"bgp-with-advertisement"},
-					},
-				},
-				true,
-				ipfamily.IPv4,
-				[]metallbv1beta1.Community{}),
-			ginkgo.Entry("IPV4 - community from CRD - legacy",
-				"192.168.10.0/24",
-				"192.168.16.0/24",
-				metallbv1beta1.BGPAdvertisement{
-					ObjectMeta: metav1.ObjectMeta{Name: "advertisement"},
-					Spec: metallbv1beta1.BGPAdvertisementSpec{
-						Communities:    []string{"NO_ADVERTISE"},
-						IPAddressPools: []string{"bgp-with-advertisement"},
-					},
-				},
-				true,
-				ipfamily.IPv4,
-				[]metallbv1beta1.Community{noAdvCommunity}),
-			ginkgo.Entry("IPV4 - localpref - legacy",
-				"192.168.10.0/24",
-				"192.168.16.0/24",
-				metallbv1beta1.BGPAdvertisement{
-					ObjectMeta: metav1.ObjectMeta{Name: "advertisement"},
-					Spec: metallbv1beta1.BGPAdvertisementSpec{
-						LocalPref:      50,
-						IPAddressPools: []string{"bgp-with-advertisement"},
-					},
-				},
-				true,
-				ipfamily.IPv4,
-				[]metallbv1beta1.Community{}),
 			ginkgo.Entry("IPV4 - ip pool selector",
 				"192.168.10.0/24",
 				"192.168.16.0/24",
@@ -959,7 +906,6 @@ var _ = ginkgo.Describe("BGP", func() {
 						},
 					},
 				},
-				false,
 				ipfamily.IPv4,
 				[]metallbv1beta1.Community{}),
 			ginkgo.Entry("IPV6 - community and localpref",
@@ -973,7 +919,6 @@ var _ = ginkgo.Describe("BGP", func() {
 						IPAddressPools: []string{"bgp-with-advertisement"},
 					},
 				},
-				false,
 				ipfamily.IPv6,
 				[]metallbv1beta1.Community{}),
 			ginkgo.Entry("IPV6 - community",
@@ -986,7 +931,6 @@ var _ = ginkgo.Describe("BGP", func() {
 						IPAddressPools: []string{"bgp-with-advertisement"},
 					},
 				},
-				false,
 				ipfamily.IPv6,
 				[]metallbv1beta1.Community{}),
 			ginkgo.Entry("IPV6 - community from CRD",
@@ -999,20 +943,6 @@ var _ = ginkgo.Describe("BGP", func() {
 						IPAddressPools: []string{"bgp-with-advertisement"},
 					},
 				},
-				false,
-				ipfamily.IPv6,
-				[]metallbv1beta1.Community{noAdvCommunity}),
-			ginkgo.Entry("IPV6 - community from CRD - legacy",
-				"fc00:f853:0ccd:e799::0-fc00:f853:0ccd:e799::18",
-				"fc00:f853:0ccd:e799::19-fc00:f853:0ccd:e799::26",
-				metallbv1beta1.BGPAdvertisement{
-					ObjectMeta: metav1.ObjectMeta{Name: "advertisement"},
-					Spec: metallbv1beta1.BGPAdvertisementSpec{
-						Communities:    []string{"NO_ADVERTISE"},
-						IPAddressPools: []string{"bgp-with-advertisement"},
-					},
-				},
-				true,
 				ipfamily.IPv6,
 				[]metallbv1beta1.Community{noAdvCommunity}),
 			ginkgo.Entry("IPV6 - localpref",
@@ -1025,7 +955,6 @@ var _ = ginkgo.Describe("BGP", func() {
 						IPAddressPools: []string{"bgp-with-advertisement"},
 					},
 				},
-				false,
 				ipfamily.IPv6,
 				[]metallbv1beta1.Community{}),
 			ginkgo.Entry("FRR - IPV6 - large community and localpref",
@@ -1039,7 +968,6 @@ var _ = ginkgo.Describe("BGP", func() {
 						IPAddressPools: []string{"bgp-with-advertisement"},
 					},
 				},
-				false,
 				ipfamily.IPv6,
 				[]metallbv1beta1.Community{}))
 	})
diff --git a/e2etest/pkg/config/parse.go b/e2etest/pkg/config/parse.go
index a7636861..552ec059 100644
--- a/e2etest/pkg/config/parse.go
+++ b/e2etest/pkg/config/parse.go
@@ -3,9 +3,8 @@
 package config
 
 import (
-	metallbv1beta1 "go.universe.tf/metallb/api/v1beta1"
 	"go.universe.tf/e2etest/pkg/pointer"
-	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	metallbv1beta1 "go.universe.tf/metallb/api/v1beta1"
 )
 
 const BGP = "bgp"
@@ -30,34 +29,6 @@ func BFDProfileWithDefaults(profile metallbv1beta1.BFDProfile, multiHop bool) me
 	return res
 }
 
-// IPAddressPoolToLegacy converts the given IPAddressPool to the legacy addresspool.
-func IPAddressPoolToLegacy(ipAddressPool metallbv1beta1.IPAddressPool, protocol string, bgpAdv []metallbv1beta1.BGPAdvertisement) metallbv1beta1.AddressPool {
-	res := metallbv1beta1.AddressPool{
-		ObjectMeta: v1.ObjectMeta{
-			Name: ipAddressPool.Name,
-		},
-		Spec: metallbv1beta1.AddressPoolSpec{
-			Protocol:          protocol,
-			Addresses:         make([]string, 0),
-			AutoAssign:        ipAddressPool.Spec.AutoAssign,
-			BGPAdvertisements: make([]metallbv1beta1.LegacyBgpAdvertisement, 0),
-		},
-	}
-	res.Spec.Addresses = append(res.Spec.Addresses, ipAddressPool.Spec.Addresses...)
-
-	for _, adv := range bgpAdv {
-		legacy := metallbv1beta1.LegacyBgpAdvertisement{
-			AggregationLength:   adv.Spec.AggregationLength,
-			AggregationLengthV6: adv.Spec.AggregationLengthV6,
-			LocalPref:           adv.Spec.LocalPref,
-			Communities:         make([]string, 0),
-		}
-		legacy.Communities = append(legacy.Communities, adv.Spec.Communities...)
-		res.Spec.BGPAdvertisements = append(res.Spec.BGPAdvertisements, legacy)
-	}
-	return res
-}
-
 func valueWithDefault(v *uint32, def uint32) *uint32 {
 	if v != nil {
 		return v
diff --git a/e2etest/pkg/config/update.go b/e2etest/pkg/config/update.go
index 6a1dee2e..b44380a0 100644
--- a/e2etest/pkg/config/update.go
+++ b/e2etest/pkg/config/update.go
@@ -16,17 +16,16 @@ import (
 )
 
 type Resources struct {
-	Pools              []metallbv1beta1.IPAddressPool    `json:"ipaddresspools"`
-	Peers              []metallbv1beta2.BGPPeer          `json:"bgppeers"`
-	BFDProfiles        []metallbv1beta1.BFDProfile       `json:"bfdprofiles"`
-	BGPAdvs            []metallbv1beta1.BGPAdvertisement `json:"bgpadvertisements"`
-	L2Advs             []metallbv1beta1.L2Advertisement  `json:"l2advertisements"`
-	LegacyAddressPools []metallbv1beta1.AddressPool      `json:"legacyaddresspools"`
-	Communities        []metallbv1beta1.Community        `json:"communities"`
-	PasswordSecrets    map[string]corev1.Secret          `json:"passwordsecrets"`
-	Nodes              []corev1.Node                     `json:"nodes"`
-	Namespaces         []corev1.Namespace                `json:"namespaces"`
-	BGPExtras          corev1.ConfigMap                  `json:"bgpextras"`
+	Pools           []metallbv1beta1.IPAddressPool    `json:"ipaddresspools"`
+	Peers           []metallbv1beta2.BGPPeer          `json:"bgppeers"`
+	BFDProfiles     []metallbv1beta1.BFDProfile       `json:"bfdprofiles"`
+	BGPAdvs         []metallbv1beta1.BGPAdvertisement `json:"bgpadvertisements"`
+	L2Advs          []metallbv1beta1.L2Advertisement  `json:"l2advertisements"`
+	Communities     []metallbv1beta1.Community        `json:"communities"`
+	PasswordSecrets map[string]corev1.Secret          `json:"passwordsecrets"`
+	Nodes           []corev1.Node                     `json:"nodes"`
+	Namespaces      []corev1.Namespace                `json:"namespaces"`
+	BGPExtras       corev1.ConfigMap                  `json:"bgpextras"`
 }
 
 type Updater interface {
@@ -118,12 +117,6 @@ func (o beta1Updater) Update(r Resources) error {
 		key++
 	}
 
-	for _, legacyPool := range r.LegacyAddressPools {
-		objects[key] = legacyPool.DeepCopy()
-		oldValues[key] = legacyPool.DeepCopy()
-		key++
-	}
-
 	for _, community := range r.Communities {
 		objects[key] = community.DeepCopy()
 		oldValues[key] = community.DeepCopy()
@@ -140,9 +133,6 @@ func (o beta1Updater) Update(r Resources) error {
 			case *metallbv1beta1.IPAddressPool:
 				old := oldValues[i].(*metallbv1beta1.IPAddressPool)
 				toChange.Spec = *old.Spec.DeepCopy()
-			case *metallbv1beta1.AddressPool:
-				old := oldValues[i].(*metallbv1beta1.AddressPool)
-				toChange.Spec = *old.Spec.DeepCopy()
 			case *metallbv1beta1.BFDProfile:
 				old := oldValues[i].(*metallbv1beta1.BFDProfile)
 				toChange.Spec = *old.Spec.DeepCopy()
@@ -190,10 +180,6 @@ func (o beta1Updater) Clean() error {
 	if err != nil {
 		return err
 	}
-	err = o.cli.DeleteAllOf(context.Background(), &metallbv1beta1.AddressPool{}, client.InNamespace(o.namespace))
-	if err != nil {
-		return err
-	}
 	err = o.cli.DeleteAllOf(context.Background(), &metallbv1beta1.Community{}, client.InNamespace(o.namespace))
 	if err != nil {
 		return err
diff --git a/e2etest/pkg/k8s/reporter.go b/e2etest/pkg/k8s/reporter.go
index 5bd28dda..325faf76 100644
--- a/e2etest/pkg/k8s/reporter.go
+++ b/e2etest/pkg/k8s/reporter.go
@@ -51,7 +51,6 @@ func InitReporter(kubeconfig, path, namespace string) *k8sreporter.KubernetesRep
 	// The list of CRDs we want to dump
 	crds := []k8sreporter.CRData{
 		{Cr: &metallbv1beta1.IPAddressPoolList{}},
-		{Cr: &metallbv1beta1.AddressPoolList{}},
 		{Cr: &metallbv1beta2.BGPPeerList{}},
 		{Cr: &metallbv1beta1.L2AdvertisementList{}},
 		{Cr: &metallbv1beta1.BGPAdvertisementList{}},
diff --git a/e2etest/webhookstests/webhooks.go b/e2etest/webhookstests/webhooks.go
index 1fbf4edb..f86e332e 100644
--- a/e2etest/webhookstests/webhooks.go
+++ b/e2etest/webhookstests/webhooks.go
@@ -30,9 +30,9 @@ import (
 	. "github.com/onsi/gomega"
 	"github.com/openshift-kni/k8sreporter"
 
+	"go.universe.tf/e2etest/pkg/pointer"
 	metallbv1beta1 "go.universe.tf/metallb/api/v1beta1"
 	metallbv1beta2 "go.universe.tf/metallb/api/v1beta2"
-	"go.universe.tf/e2etest/pkg/pointer"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/kubernetes/test/e2e/framework"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -109,58 +109,6 @@ var _ = ginkgo.Describe("Webhooks", func() {
 		})
 	})
 
-	ginkgo.Context("for Legacy AddressPool", func() {
-		ginkgo.It("Should recognize overlapping addresses in two AddressPools", func() {
-			ginkgo.By("Creating first AddrssPool")
-			resources := config.Resources{
-				LegacyAddressPools: []metallbv1beta1.AddressPool{
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name: "webhooks-test1",
-						},
-						Spec: metallbv1beta1.AddressPoolSpec{
-							Addresses: []string{
-								"1.1.1.1-1.1.1.100",
-							},
-							Protocol: string(config.L2),
-						},
-					},
-				},
-			}
-			err := ConfigUpdater.Update(resources)
-			framework.ExpectNoError(err)
-
-			ginkgo.By("Creating second AddressPool with overlapping addresses defined by address range")
-			resources.LegacyAddressPools = append(resources.LegacyAddressPools,
-				metallbv1beta1.AddressPool{
-					ObjectMeta: metav1.ObjectMeta{
-						Name: "webhooks-test2",
-					},
-					Spec: metallbv1beta1.AddressPoolSpec{
-						Addresses: []string{
-							"1.1.1.15-1.1.1.20",
-						},
-						Protocol: string(config.L2),
-					},
-				},
-			)
-			err = ConfigUpdater.Update(resources)
-			framework.ExpectError(err)
-			Expect(err.Error()).To(ContainSubstring("overlaps with already defined CIDR"))
-
-			ginkgo.By("Creating second valid AddressPool")
-			resources.LegacyAddressPools[1].Spec.Addresses = []string{"1.1.1.101-1.1.1.200"}
-			err = ConfigUpdater.Update(resources)
-			framework.ExpectNoError(err)
-
-			ginkgo.By("Updating second AddressPool addresses to overlapping addresses defined by network prefix")
-			resources.LegacyAddressPools[1].Spec.Addresses = []string{"1.1.1.0/24"}
-			err = ConfigUpdater.Update(resources)
-			framework.ExpectError(err)
-			Expect(err.Error()).To(ContainSubstring("overlaps with already defined CIDR"))
-		})
-	})
-
 	ginkgo.Context("for BGPAdvertisement", func() {
 		ginkgo.It("Should recognize invalid AggregationLength", func() {
 			ginkgo.By("Creating AddressPool")
@@ -417,21 +365,6 @@ var _ = ginkgo.DescribeTable("Webhooks namespace validation",
 			},
 		},
 	}),
-	ginkgo.Entry("Should reject creating Legacy AddressPool in a different namespace", &config.Resources{
-		LegacyAddressPools: []metallbv1beta1.AddressPool{
-			{
-				ObjectMeta: metav1.ObjectMeta{
-					Name: "webhooks-test1",
-				},
-				Spec: metallbv1beta1.AddressPoolSpec{
-					Addresses: []string{
-						"1.1.1.1-1.1.1.100",
-					},
-					Protocol: string(config.L2),
-				},
-			},
-		},
-	}),
 	ginkgo.Entry("Should reject creating BGPPeer in a different namespace", &config.Resources{
 		Peers: []metallbv1beta2.BGPPeer{
 			{
diff --git a/internal/config/config_test.go b/internal/config/config_test.go
index 5d264afd..60855581 100644
--- a/internal/config/config_test.go
+++ b/internal/config/config_test.go
@@ -2319,225 +2319,6 @@ func TestParse(t *testing.T) {
 				},
 			},
 		},
-		{
-			desc: "config mixing legacy pools with IP pools",
-			crs: ClusterResources{
-				Peers: []v1beta2.BGPPeer{
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name: "peer1",
-						},
-						Spec: v1beta2.BGPPeerSpec{
-							MyASN:        42,
-							ASN:          142,
-							Address:      "1.2.3.4",
-							Port:         1179,
-							HoldTime:     metav1.Duration{Duration: 180 * time.Second},
-							RouterID:     "10.20.30.40",
-							SrcAddress:   "10.20.30.40",
-							EBGPMultiHop: true,
-						},
-					},
-				},
-				Pools: []v1beta1.IPAddressPool{
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name: "pool1",
-						},
-						Spec: v1beta1.IPAddressPoolSpec{
-							Addresses: []string{
-								"10.20.0.0/16",
-								"10.50.0.0/24",
-							},
-							AvoidBuggyIPs: true,
-							AutoAssign:    pointer.BoolPtr(false),
-						},
-					},
-				},
-				LegacyAddressPools: []v1beta1.AddressPool{
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name: "legacyl2pool1",
-						},
-						Spec: v1beta1.AddressPoolSpec{
-							Addresses: []string{
-								"10.21.0.0/16",
-								"10.51.0.0/24",
-							},
-							Protocol:   string(Layer2),
-							AutoAssign: pointer.BoolPtr(false),
-						},
-					},
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name: "legacybgppool1",
-						},
-						Spec: v1beta1.AddressPoolSpec{
-							Addresses: []string{
-								"10.40.0.0/16",
-								"10.60.0.0/24",
-							},
-							Protocol:   string(BGP),
-							AutoAssign: pointer.BoolPtr(false),
-							BGPAdvertisements: []v1beta1.LegacyBgpAdvertisement{
-								{
-									AggregationLength: pointer.Int32Ptr(32),
-									LocalPref:         uint32(100),
-									Communities:       []string{"1234:2345"},
-								},
-							},
-						},
-					},
-				},
-				BGPAdvs: []v1beta1.BGPAdvertisement{
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name: "adv1",
-						},
-						Spec: v1beta1.BGPAdvertisementSpec{
-							AggregationLength: pointer.Int32Ptr(32),
-							LocalPref:         uint32(100),
-							Communities:       []string{"1234:2345"},
-							IPAddressPools:    []string{"pool1"},
-						},
-					},
-				},
-			},
-			want: &Config{
-				Peers: map[string]*Peer{
-					"peer1": {
-						Name:          "peer1",
-						MyASN:         42,
-						ASN:           142,
-						Addr:          net.ParseIP("1.2.3.4"),
-						SrcAddr:       net.ParseIP("10.20.30.40"),
-						Port:          1179,
-						HoldTime:      180 * time.Second,
-						KeepaliveTime: 60 * time.Second,
-						RouterID:      net.ParseIP("10.20.30.40"),
-						NodeSelectors: []labels.Selector{labels.Everything()},
-						EBGPMultiHop:  true,
-					},
-				},
-				Pools: &Pools{ByName: map[string]*Pool{
-					"pool1": {
-						Name:          "pool1",
-						CIDR:          []*net.IPNet{ipnet("10.20.0.0/16"), ipnet("10.50.0.0/24")},
-						AvoidBuggyIPs: true,
-						AutoAssign:    false,
-						BGPAdvertisements: []*BGPAdvertisement{
-							{
-								Name:                "adv1",
-								AggregationLength:   32,
-								AggregationLengthV6: 128,
-								LocalPref:           100,
-								Communities: func() map[community.BGPCommunity]bool {
-									c, _ := community.New("1234:2345")
-									return map[community.BGPCommunity]bool{
-										c: true,
-									}
-								}(),
-								Nodes: map[string]bool{},
-							},
-						},
-					},
-					"legacybgppool1": {
-						Name: "legacybgppool1",
-						CIDR: []*net.IPNet{ipnet("10.40.0.0/16"), ipnet("10.60.0.0/24")},
-						BGPAdvertisements: []*BGPAdvertisement{
-							{
-								AggregationLength:   32,
-								AggregationLengthV6: 128,
-								LocalPref:           100,
-								Communities: func() map[community.BGPCommunity]bool {
-									c, _ := community.New("1234:2345")
-									return map[community.BGPCommunity]bool{
-										c: true,
-									}
-								}(),
-								Nodes: map[string]bool{},
-							},
-						},
-					},
-					"legacyl2pool1": {
-						Name: "legacyl2pool1",
-						CIDR: []*net.IPNet{ipnet("10.21.0.0/16"), ipnet("10.51.0.0/24")},
-						L2Advertisements: []*L2Advertisement{{
-							Nodes:         map[string]bool{},
-							AllInterfaces: true,
-						}},
-					},
-				}},
-				BFDProfiles: map[string]*BFDProfile{},
-			},
-		},
-
-		{
-			desc: "config legacy pool with bgp communities crd",
-			crs: ClusterResources{
-				LegacyAddressPools: []v1beta1.AddressPool{
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name: "legacybgppool1",
-						},
-						Spec: v1beta1.AddressPoolSpec{
-							Addresses: []string{
-								"10.40.0.0/16",
-								"10.60.0.0/24",
-							},
-							Protocol:   string(BGP),
-							AutoAssign: pointer.BoolPtr(false),
-							BGPAdvertisements: []v1beta1.LegacyBgpAdvertisement{
-								{
-									AggregationLength: pointer.Int32Ptr(32),
-									LocalPref:         uint32(100),
-									Communities:       []string{"bar"},
-								},
-							},
-						},
-					},
-				},
-				Communities: []v1beta1.Community{
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name: "community",
-						},
-						Spec: v1beta1.CommunitySpec{
-							Communities: []v1beta1.CommunityAlias{
-								{
-									Name:  "bar",
-									Value: "64512:1234",
-								},
-							},
-						},
-					},
-				},
-			},
-			want: &Config{
-				Pools: &Pools{ByName: map[string]*Pool{
-					"legacybgppool1": {
-						Name: "legacybgppool1",
-						CIDR: []*net.IPNet{ipnet("10.40.0.0/16"), ipnet("10.60.0.0/24")},
-						BGPAdvertisements: []*BGPAdvertisement{
-							{
-								AggregationLength:   32,
-								AggregationLengthV6: 128,
-								LocalPref:           100,
-								Communities: func() map[community.BGPCommunity]bool {
-									c, _ := community.New("64512:1234")
-									return map[community.BGPCommunity]bool{
-										c: true,
-									}
-								}(),
-								Nodes: map[string]bool{},
-							},
-						},
-					},
-				}},
-				BFDProfiles: map[string]*BFDProfile{},
-				Peers:       map[string]*Peer{},
-			},
-		},
 		{
 			desc: "config IPAddressPool with large communities CR",
 			crs: ClusterResources{
@@ -2673,119 +2454,6 @@ func TestParse(t *testing.T) {
 				BFDProfiles: map[string]*BFDProfile{},
 			},
 		},
-		{
-			desc: "config legacy pool with BGP Communities CR and large communities",
-			crs: ClusterResources{
-				LegacyAddressPools: []v1beta1.AddressPool{
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name: "legacybgppool1",
-						},
-						Spec: v1beta1.AddressPoolSpec{
-							Addresses: []string{
-								"10.40.0.0/16",
-								"10.60.0.0/24",
-							},
-							Protocol:   string(BGP),
-							AutoAssign: pointer.BoolPtr(false),
-							BGPAdvertisements: []v1beta1.LegacyBgpAdvertisement{
-								{
-									AggregationLength: pointer.Int32Ptr(32),
-									LocalPref:         uint32(100),
-									Communities:       []string{"bar"},
-								},
-							},
-						},
-					},
-				},
-				Communities: []v1beta1.Community{
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name: "community",
-						},
-						Spec: v1beta1.CommunitySpec{
-							Communities: []v1beta1.CommunityAlias{
-								{
-									Name:  "bar",
-									Value: "large:123:64512:1234",
-								},
-							},
-						},
-					},
-				},
-			},
-			want: &Config{
-				Pools: &Pools{ByName: map[string]*Pool{
-					"legacybgppool1": {
-						Name: "legacybgppool1",
-						CIDR: []*net.IPNet{ipnet("10.40.0.0/16"), ipnet("10.60.0.0/24")},
-						BGPAdvertisements: []*BGPAdvertisement{
-							{
-								AggregationLength:   32,
-								AggregationLengthV6: 128,
-								LocalPref:           100,
-								Communities: func() map[community.BGPCommunity]bool {
-									c, _ := community.New("large:123:64512:1234")
-									return map[community.BGPCommunity]bool{
-										c: true,
-									}
-								}(),
-								Nodes: map[string]bool{},
-							},
-						},
-					},
-				}},
-				BFDProfiles: map[string]*BFDProfile{},
-				Peers:       map[string]*Peer{},
-			},
-		},
-		{
-			desc: "config mixing legacy pools with IP pools with overlapping ips",
-			crs: ClusterResources{
-				Pools: []v1beta1.IPAddressPool{
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name: "pool1",
-						},
-						Spec: v1beta1.IPAddressPoolSpec{
-							Addresses: []string{
-								"10.20.0.0/16",
-								"10.50.0.0/24",
-							},
-							AvoidBuggyIPs: true,
-							AutoAssign:    pointer.BoolPtr(false),
-						},
-					},
-				},
-				LegacyAddressPools: []v1beta1.AddressPool{
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name: "legacyl2pool1",
-						},
-						Spec: v1beta1.AddressPoolSpec{
-							Addresses: []string{
-								"10.20.0.0/16",
-								"10.51.0.0/24",
-							},
-							Protocol:   string(Layer2),
-							AutoAssign: pointer.BoolPtr(false),
-						},
-					},
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name: "legacybgppool1",
-						},
-						Spec: v1beta1.AddressPoolSpec{
-							Addresses: []string{
-								"10.40.0.0/16",
-								"10.60.0.0/24",
-							},
-							Protocol: string(BGP),
-						},
-					},
-				},
-			},
-		},
 		{
 			desc: "use ip pool selectors",
 			crs: ClusterResources{
@@ -3250,34 +2918,6 @@ func TestParse(t *testing.T) {
 						},
 					},
 				},
-				LegacyAddressPools: []v1beta1.AddressPool{
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name: "legacyl2pool1",
-						},
-						Spec: v1beta1.AddressPoolSpec{
-							Addresses: []string{
-								"10.21.0.0/16",
-								"10.51.0.0/24",
-							},
-							Protocol:   string(Layer2),
-							AutoAssign: pointer.BoolPtr(false),
-						},
-					},
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name: "legacybgppool1",
-						},
-						Spec: v1beta1.AddressPoolSpec{
-							Addresses: []string{
-								"10.40.0.0/16",
-								"10.60.0.0/24",
-							},
-							Protocol:   string(BGP),
-							AutoAssign: pointer.BoolPtr(false),
-						},
-					},
-				},
 				Nodes: []corev1.Node{
 					{
 						ObjectMeta: metav1.ObjectMeta{
@@ -3298,34 +2938,6 @@ func TestParse(t *testing.T) {
 			},
 			want: &Config{
 				Pools: &Pools{ByName: map[string]*Pool{
-					"legacybgppool1": {
-						Name: "legacybgppool1",
-						CIDR: []*net.IPNet{ipnet("10.40.0.0/16"), ipnet("10.60.0.0/24")},
-						BGPAdvertisements: []*BGPAdvertisement{
-							{
-								AggregationLength:   32,
-								AggregationLengthV6: 128,
-								Communities:         map[community.BGPCommunity]bool{},
-								Nodes: map[string]bool{
-									"first":  true,
-									"second": true,
-								},
-							},
-						},
-					},
-
-					"legacyl2pool1": {
-						Name: "legacyl2pool1",
-						CIDR: []*net.IPNet{ipnet("10.21.0.0/16"), ipnet("10.51.0.0/24")},
-						L2Advertisements: []*L2Advertisement{{
-							Nodes: map[string]bool{
-								"first":  true,
-								"second": true,
-							},
-							AllInterfaces: true,
-						}},
-					},
-
 					"pool1": {
 						Name:       "pool1",
 						CIDR:       []*net.IPNet{ipnet("10.20.0.0/16")},
@@ -3678,33 +3290,6 @@ func TestParse(t *testing.T) {
 				BFDProfiles: map[string]*BFDProfile{},
 			},
 		},
-		{
-			desc: "config legacy pool with invalid community",
-			crs: ClusterResources{
-				LegacyAddressPools: []v1beta1.AddressPool{
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name: "legacybgppool1",
-						},
-						Spec: v1beta1.AddressPoolSpec{
-							Addresses: []string{
-								"10.40.0.0/16",
-								"10.60.0.0/24",
-							},
-							Protocol:   string(BGP),
-							AutoAssign: pointer.BoolPtr(false),
-							BGPAdvertisements: []v1beta1.LegacyBgpAdvertisement{
-								{
-									AggregationLength: pointer.Int32Ptr(32),
-									LocalPref:         uint32(100),
-									Communities:       []string{"1234"},
-								},
-							},
-						},
-					},
-				},
-			},
-		},
 	}
 
 	for _, test := range tests {
diff --git a/internal/config/validation_test.go b/internal/config/validation_test.go
index b287ea79..441b0d35 100644
--- a/internal/config/validation_test.go
+++ b/internal/config/validation_test.go
@@ -82,23 +82,6 @@ func TestValidate(t *testing.T) {
 			},
 			mustFail: true,
 		},
-		{
-			desc: "large BGP community inside legacy pool",
-			config: ClusterResources{
-				LegacyAddressPools: []v1beta1.AddressPool{
-					{
-						Spec: v1beta1.AddressPoolSpec{
-							BGPAdvertisements: []v1beta1.LegacyBgpAdvertisement{
-								{
-									Communities: []string{"large:123:456:789"},
-								},
-							},
-						},
-					},
-				},
-			},
-			mustFail: true,
-		},
 		{
 			desc: "large BGP community inside BGP Advertisement",
 			config: ClusterResources{
diff --git a/internal/config/validator_test.go b/internal/config/validator_test.go
index 50e142c0..1c3a545e 100644
--- a/internal/config/validator_test.go
+++ b/internal/config/validator_test.go
@@ -84,22 +84,6 @@ func TestResetTransientErrorsFields(t *testing.T) {
 						},
 					},
 				},
-				LegacyAddressPools: []metallbv1beta1.AddressPool{
-					{
-						Spec: metallbv1beta1.AddressPoolSpec{
-							BGPAdvertisements: []metallbv1beta1.LegacyBgpAdvertisement{
-								{
-									Communities: []string{
-										"11111:11aaaa",
-										"larg:12345:12345:12345",
-										"alias",
-										"myCommunityAlias",
-									},
-								},
-							},
-						},
-					},
-				},
 			},
 			expected: ClusterResources{
 				Peers: []metallbv1beta2.BGPPeer{
@@ -135,20 +119,6 @@ func TestResetTransientErrorsFields(t *testing.T) {
 						},
 					},
 				},
-				LegacyAddressPools: []metallbv1beta1.AddressPool{
-					{
-						Spec: metallbv1beta1.AddressPoolSpec{
-							BGPAdvertisements: []metallbv1beta1.LegacyBgpAdvertisement{
-								{
-									Communities: []string{
-										"11111:11aaaa",
-										"larg:12345:12345:12345",
-									},
-								},
-							},
-						},
-					},
-				},
 			},
 		},
 	}
diff --git a/internal/k8s/controllers/config_controller_test.go b/internal/k8s/controllers/config_controller_test.go
index b56ad6e1..448ede8a 100644
--- a/internal/k8s/controllers/config_controller_test.go
+++ b/internal/k8s/controllers/config_controller_test.go
@@ -271,20 +271,6 @@ var (
 			"bgpsecret": {Type: corev1.SecretTypeBasicAuth, ObjectMeta: metav1.ObjectMeta{Name: "bgpsecret", Namespace: testNamespace},
 				Data: map[string][]byte{"password": []byte("nopass")}},
 		},
-		LegacyAddressPools: []v1beta1.AddressPool{
-			{
-				ObjectMeta: metav1.ObjectMeta{
-					Name:      "legacypool1",
-					Namespace: testNamespace,
-				},
-				Spec: v1beta1.AddressPoolSpec{
-					Addresses: []string{
-						"10.21.0.0/16",
-					},
-					Protocol: "bgp",
-				},
-			},
-		},
 		Communities: []v1beta1.Community{
 			{
 				ObjectMeta: metav1.ObjectMeta{
diff --git a/internal/k8s/controllers/config_conversion_test.go b/internal/k8s/controllers/config_conversion_test.go
index 63cb1e9a..4b011a5a 100644
--- a/internal/k8s/controllers/config_conversion_test.go
+++ b/internal/k8s/controllers/config_conversion_test.go
@@ -84,32 +84,6 @@ func TestConversionIsStable(t *testing.T) {
 			},
 		},
 	}
-	legacyAddressPools := []v1beta1.AddressPool{
-		{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:      "legacypool1",
-				Namespace: testNamespace,
-			},
-			Spec: v1beta1.AddressPoolSpec{
-				Addresses: []string{
-					"10.21.0.0/16",
-				},
-				Protocol: "bgp",
-			},
-		},
-		{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:      "legacypool2",
-				Namespace: testNamespace,
-			},
-			Spec: v1beta1.AddressPoolSpec{
-				Addresses: []string{
-					"10.22.0.0/16",
-				},
-				Protocol: "layer2",
-			},
-		},
-	}
 	bgpAdvs := []v1beta1.BGPAdvertisement{
 		{
 			ObjectMeta: metav1.ObjectMeta{
@@ -204,16 +178,15 @@ func TestConversionIsStable(t *testing.T) {
 	}
 
 	resources := config.ClusterResources{
-		Pools:              pools,
-		Peers:              peers,
-		BFDProfiles:        bfdProfiles,
-		L2Advs:             l2Advs,
-		BGPAdvs:            bgpAdvs,
-		LegacyAddressPools: legacyAddressPools,
-		Communities:        communities,
-		PasswordSecrets:    map[string]v1.Secret{},
-		Nodes:              nodes,
-		Namespaces:         namespaces,
+		Pools:           pools,
+		Peers:           peers,
+		BFDProfiles:     bfdProfiles,
+		L2Advs:          l2Advs,
+		BGPAdvs:         bgpAdvs,
+		Communities:     communities,
+		PasswordSecrets: map[string]v1.Secret{},
+		Nodes:           nodes,
+		Namespaces:      namespaces,
 	}
 
 	firstConfig, err := toConfig(resources, config.DontValidate)
@@ -233,7 +206,6 @@ func TestConversionIsStable(t *testing.T) {
 		shuffleObjects(resources.BGPAdvs)
 		shuffleObjects(resources.L2Advs)
 		shuffleObjects(resources.Communities)
-		shuffleObjects(resources.LegacyAddressPools)
 		shuffleObjects(resources.Nodes)
 		shuffleObjects(resources.Namespaces)
 
diff --git a/internal/k8s/controllers/fakeclient_test.go b/internal/k8s/controllers/fakeclient_test.go
index 3498d3d8..edbdecc9 100644
--- a/internal/k8s/controllers/fakeclient_test.go
+++ b/internal/k8s/controllers/fakeclient_test.go
@@ -87,10 +87,6 @@ func objectsFromResources(r config.ClusterResources) []client.Object {
 		objects = append(objects, l2Adv.DeepCopy())
 	}
 
-	for _, legacyPool := range r.LegacyAddressPools {
-		objects = append(objects, legacyPool.DeepCopy())
-	}
-
 	for _, community := range r.Communities {
 		objects = append(objects, community.DeepCopy())
 	}
diff --git a/internal/k8s/controllers/pool_controller_test.go b/internal/k8s/controllers/pool_controller_test.go
index 82685cab..8f7fc515 100644
--- a/internal/k8s/controllers/pool_controller_test.go
+++ b/internal/k8s/controllers/pool_controller_test.go
@@ -25,7 +25,6 @@ import (
 	"github.com/google/go-cmp/cmp/cmpopts"
 	v1beta1 "go.universe.tf/metallb/api/v1beta1"
 	metallbcfg "go.universe.tf/metallb/internal/config"
-	"go.universe.tf/metallb/internal/pointer"
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/client-go/kubernetes/scheme"
@@ -150,27 +149,6 @@ var (
 				},
 			},
 		},
-		LegacyAddressPools: []v1beta1.AddressPool{
-			{
-				ObjectMeta: v1.ObjectMeta{
-					Name:      "legacypool1",
-					Namespace: testNamespace,
-				},
-				Spec: v1beta1.AddressPoolSpec{
-					Addresses: []string{
-						"10.21.0.0/16",
-					},
-					Protocol: "bgp",
-					BGPAdvertisements: []v1beta1.LegacyBgpAdvertisement{
-						{
-							AggregationLength: pointer.Int32Ptr(32),
-							LocalPref:         uint32(100),
-							Communities:       []string{"bar"},
-						},
-					},
-				},
-			},
-		},
 		Communities: []v1beta1.Community{
 			{
 				ObjectMeta: v1.ObjectMeta{
diff --git a/internal/k8s/webhooks/webhookv1beta1/addresspool_webhook_test.go b/internal/k8s/webhooks/webhookv1beta1/addresspool_webhook_test.go
deleted file mode 100644
index 88323e79..00000000
--- a/internal/k8s/webhooks/webhookv1beta1/addresspool_webhook_test.go
+++ /dev/null
@@ -1,152 +0,0 @@
-// SPDX-License-Identifier:Apache-2.0
-
-package webhookv1beta1
-
-import (
-	"testing"
-
-	"github.com/go-kit/log"
-	"github.com/google/go-cmp/cmp"
-	"go.universe.tf/metallb/api/v1beta1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-)
-
-const (
-	MetalLBTestNameSpace = "metallb-test-namespace"
-)
-
-func TestValidateAddressPool(t *testing.T) {
-	MetalLBNamespace = MetalLBTestNameSpace
-	addressPool := v1beta1.AddressPool{
-		ObjectMeta: metav1.ObjectMeta{
-			Name:      "test-addresspool",
-			Namespace: MetalLBTestNameSpace,
-		},
-	}
-	Logger = log.NewNopLogger()
-
-	toRestoreAddresspools := getExistingAddressPools
-	getExistingAddressPools = func() (*v1beta1.AddressPoolList, error) {
-		return &v1beta1.AddressPoolList{
-			Items: []v1beta1.AddressPool{
-				addressPool,
-			},
-		}, nil
-	}
-	toRestoreIPAddressPools := getExistingIPAddressPools
-	getExistingIPAddressPools = func() (*v1beta1.IPAddressPoolList, error) {
-		return &v1beta1.IPAddressPoolList{}, nil
-	}
-
-	defer func() {
-		getExistingAddressPools = toRestoreAddresspools
-		getExistingIPAddressPools = toRestoreIPAddressPools
-	}()
-
-	tests := []struct {
-		desc             string
-		addressPool      *v1beta1.AddressPool
-		isNewAddressPool bool
-		failValidate     bool
-		expected         *v1beta1.AddressPoolList
-	}{
-		{
-			desc: "Second AddressPool",
-			addressPool: &v1beta1.AddressPool{
-				ObjectMeta: metav1.ObjectMeta{
-					Name:      "test-addresspool1",
-					Namespace: MetalLBTestNameSpace,
-				},
-			},
-			isNewAddressPool: true,
-			expected: &v1beta1.AddressPoolList{
-				Items: []v1beta1.AddressPool{
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name:      "test-addresspool",
-							Namespace: MetalLBTestNameSpace,
-						},
-					},
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name:      "test-addresspool1",
-							Namespace: MetalLBTestNameSpace,
-						},
-					},
-				},
-			},
-		},
-		{
-			desc: "Same AddressPool, update",
-			addressPool: &v1beta1.AddressPool{
-				ObjectMeta: metav1.ObjectMeta{
-					Name:      "test-addresspool",
-					Namespace: MetalLBTestNameSpace,
-				},
-			},
-			isNewAddressPool: false,
-			expected: &v1beta1.AddressPoolList{
-				Items: []v1beta1.AddressPool{
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name:      "test-addresspool",
-							Namespace: MetalLBTestNameSpace,
-						},
-					},
-				},
-			},
-		},
-		{
-			desc: "Validation Fails",
-			addressPool: &v1beta1.AddressPool{
-				ObjectMeta: metav1.ObjectMeta{
-					Name:      "test-addresspool",
-					Namespace: MetalLBTestNameSpace,
-				},
-			},
-			isNewAddressPool: false,
-			expected: &v1beta1.AddressPoolList{
-				Items: []v1beta1.AddressPool{
-					{
-						ObjectMeta: metav1.ObjectMeta{
-							Name:      "test-addresspool",
-							Namespace: MetalLBTestNameSpace,
-						},
-					},
-				},
-			},
-			failValidate: true,
-		},
-		{
-			desc: "Validation must fail if created in different namespace",
-			addressPool: &v1beta1.AddressPool{
-				ObjectMeta: metav1.ObjectMeta{
-					Name:      "test-addresspool2",
-					Namespace: "default",
-				},
-			},
-			isNewAddressPool: true,
-			expected:         nil,
-			failValidate:     true,
-		},
-	}
-
-	for _, test := range tests {
-		var err error
-		mock := &mockValidator{}
-		Validator = mock
-		mock.forceError = test.failValidate
-
-		if test.isNewAddressPool {
-			err = validateAddressPoolCreate(test.addressPool)
-		} else {
-			err = validateAddressPoolUpdate(test.addressPool, nil)
-		}
-		if test.failValidate && err == nil {
-			t.Fatalf("test %s failed, expecting error", test.desc)
-		}
-		if !cmp.Equal(test.expected, mock.pools) {
-			t.Fatalf("test %s failed, %s", test.desc, cmp.Diff(test.expected, mock.pools))
-		}
-	}
-}
diff --git a/internal/k8s/webhooks/webhookv1beta1/bfdprofile_webhook_test.go b/internal/k8s/webhooks/webhookv1beta1/bfdprofile_webhook_test.go
index 3ded103d..57bc88f6 100644
--- a/internal/k8s/webhooks/webhookv1beta1/bfdprofile_webhook_test.go
+++ b/internal/k8s/webhooks/webhookv1beta1/bfdprofile_webhook_test.go
@@ -13,6 +13,10 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
+const (
+	MetalLBTestNameSpace = "metallb-test-namespace"
+)
+
 func TestValidateBFDProfile(t *testing.T) {
 	MetalLBNamespace = MetalLBTestNameSpace
 	Logger = log.NewNopLogger()
diff --git a/internal/k8s/webhooks/webhookv1beta1/bgpadvertisement_webhook_test.go b/internal/k8s/webhooks/webhookv1beta1/bgpadvertisement_webhook_test.go
index 66654f5f..186df375 100644
--- a/internal/k8s/webhooks/webhookv1beta1/bgpadvertisement_webhook_test.go
+++ b/internal/k8s/webhooks/webhookv1beta1/bgpadvertisement_webhook_test.go
@@ -31,10 +31,6 @@ func TestValidateBGPAdvertisement(t *testing.T) {
 			},
 		}, nil
 	}
-	toRestoreAddresspools := getExistingAddressPools
-	getExistingAddressPools = func() (*v1beta1.AddressPoolList, error) {
-		return &v1beta1.AddressPoolList{}, nil
-	}
 	toRestoreIPAddressPools := getExistingIPAddressPools
 	getExistingIPAddressPools = func() (*v1beta1.IPAddressPoolList, error) {
 		return &v1beta1.IPAddressPoolList{}, nil
@@ -46,7 +42,6 @@ func TestValidateBGPAdvertisement(t *testing.T) {
 
 	defer func() {
 		getExistingBGPAdvs = toRestore
-		getExistingAddressPools = toRestoreAddresspools
 		getExistingIPAddressPools = toRestoreIPAddressPools
 		getExistingNodes = toRestoreNodes
 	}()
diff --git a/internal/k8s/webhooks/webhookv1beta1/community_webhook_test.go b/internal/k8s/webhooks/webhookv1beta1/community_webhook_test.go
index 0cf80d5d..39cc038c 100644
--- a/internal/k8s/webhooks/webhookv1beta1/community_webhook_test.go
+++ b/internal/k8s/webhooks/webhookv1beta1/community_webhook_test.go
@@ -134,7 +134,7 @@ func TestValidateCommunity(t *testing.T) {
 			t.Fatalf("test %s failed, expecting error", test.desc)
 		}
 		if !cmp.Equal(test.expected, mock.communities) {
-			t.Fatalf("test %s failed, %s", test.desc, cmp.Diff(test.expected, mock.pools))
+			t.Fatalf("test %s failed, %s", test.desc, cmp.Diff(test.expected, mock.communities))
 		}
 	}
 }
diff --git a/internal/k8s/webhooks/webhookv1beta1/ipaddresspool_webhook_test.go b/internal/k8s/webhooks/webhookv1beta1/ipaddresspool_webhook_test.go
index 3cdd2254..abc4ad0c 100644
--- a/internal/k8s/webhooks/webhookv1beta1/ipaddresspool_webhook_test.go
+++ b/internal/k8s/webhooks/webhookv1beta1/ipaddresspool_webhook_test.go
@@ -21,10 +21,6 @@ func TestValidateIPAddressPool(t *testing.T) {
 	}
 	Logger = log.NewNopLogger()
 
-	toRestoreAddresspools := getExistingAddressPools
-	getExistingAddressPools = func() (*v1beta1.AddressPoolList, error) {
-		return &v1beta1.AddressPoolList{}, nil
-	}
 	toRestoreIPAddressPools := getExistingIPAddressPools
 	getExistingIPAddressPools = func() (*v1beta1.IPAddressPoolList, error) {
 		return &v1beta1.IPAddressPoolList{
@@ -35,7 +31,6 @@ func TestValidateIPAddressPool(t *testing.T) {
 	}
 
 	defer func() {
-		getExistingAddressPools = toRestoreAddresspools
 		getExistingIPAddressPools = toRestoreIPAddressPools
 	}()
 
diff --git a/internal/k8s/webhooks/webhookv1beta1/l2advertisement_webhook_test.go b/internal/k8s/webhooks/webhookv1beta1/l2advertisement_webhook_test.go
index 2f20765e..a0ce3d1c 100644
--- a/internal/k8s/webhooks/webhookv1beta1/l2advertisement_webhook_test.go
+++ b/internal/k8s/webhooks/webhookv1beta1/l2advertisement_webhook_test.go
@@ -30,10 +30,6 @@ func TestValidateL2Advertisement(t *testing.T) {
 			},
 		}, nil
 	}
-	toRestoreAddresspools := getExistingAddressPools
-	getExistingAddressPools = func() (*v1beta1.AddressPoolList, error) {
-		return &v1beta1.AddressPoolList{}, nil
-	}
 	toRestoreIPAddressPools := getExistingIPAddressPools
 	getExistingIPAddressPools = func() (*v1beta1.IPAddressPoolList, error) {
 		return &v1beta1.IPAddressPoolList{}, nil
@@ -41,7 +37,6 @@ func TestValidateL2Advertisement(t *testing.T) {
 
 	defer func() {
 		getExistingL2Advs = toRestore
-		getExistingAddressPools = toRestoreAddresspools
 		getExistingIPAddressPools = toRestoreIPAddressPools
 	}()
 
diff --git a/internal/k8s/webhooks/webhookv1beta1/mock_validator_test.go b/internal/k8s/webhooks/webhookv1beta1/mock_validator_test.go
index 471fdcea..9ec9ccbd 100644
--- a/internal/k8s/webhooks/webhookv1beta1/mock_validator_test.go
+++ b/internal/k8s/webhooks/webhookv1beta1/mock_validator_test.go
@@ -10,7 +10,6 @@ import (
 )
 
 type mockValidator struct {
-	pools          *v1beta1.AddressPoolList
 	ipAddressPools *v1beta1.IPAddressPoolList
 	bgpAdvs        *v1beta1.BGPAdvertisementList
 	l2Advs         *v1beta1.L2AdvertisementList
@@ -22,8 +21,6 @@ type mockValidator struct {
 func (m *mockValidator) Validate(objects ...client.ObjectList) error {
 	for _, obj := range objects { // assuming one object per type
 		switch list := obj.(type) {
-		case *v1beta1.AddressPoolList:
-			m.pools = list
 		case *v1beta1.BGPAdvertisementList:
 			m.bgpAdvs = list
 		case *v1beta1.L2AdvertisementList: