diff --git a/exp/ipam/internal/webhooks/ipaddressclaim.go b/exp/ipam/internal/webhooks/ipaddressclaim.go index c24021955f5b..92cde704da30 100644 --- a/exp/ipam/internal/webhooks/ipaddressclaim.go +++ b/exp/ipam/internal/webhooks/ipaddressclaim.go @@ -28,6 +28,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" ipamv1 "sigs.k8s.io/cluster-api/exp/ipam/api/v1beta1" ) @@ -54,6 +55,15 @@ func (webhook *IPAddressClaim) ValidateCreate(_ context.Context, obj runtime.Obj return nil, apierrors.NewBadRequest(fmt.Sprintf("expected an IPAddressClaim but got a %T", obj)) } + // Ensures the IPAddressClaim has a cluster name label, to pause IPAddressClaim when the root cluster is paused + // and essentially prevent clusterctl move from failing. + if claim.GetObjectMeta().GetLabels()[clusterv1.ClusterNameLabel] == "" { + return nil, field.Invalid( + field.NewPath("metadata.labels"), + claim.GetObjectMeta().GetLabels(), + "the IPAddressClaim needs to have the cluster name label 'cluster.x-k8s.io/cluster-name'") + } + if claim.Spec.PoolRef.APIGroup == nil { return nil, field.Invalid( field.NewPath("spec.poolRef.apiGroup"), diff --git a/exp/ipam/internal/webhooks/ipaddressclaim_test.go b/exp/ipam/internal/webhooks/ipaddressclaim_test.go index 2f9f5025a6d0..f2963ef0fabb 100644 --- a/exp/ipam/internal/webhooks/ipaddressclaim_test.go +++ b/exp/ipam/internal/webhooks/ipaddressclaim_test.go @@ -24,6 +24,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/utils/ptr" + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" ipamv1 "sigs.k8s.io/cluster-api/exp/ipam/api/v1beta1" ) @@ -48,8 +49,12 @@ func TestIPAddressClaimValidateCreate(t *testing.T) { expectErr bool }{ { - name: "should accept a valid claim", - claim: getClaim(func(addr *ipamv1.IPAddressClaim) {}), + name: "should accept a valid claim", + claim: getClaim(func(addr *ipamv1.IPAddressClaim) { + addr.GetObjectMeta().SetLabels(map[string]string{ + clusterv1.ClusterNameLabel: "test-cluster", + }) + }), expectErr: false, }, { @@ -59,6 +64,11 @@ func TestIPAddressClaimValidateCreate(t *testing.T) { }), expectErr: true, }, + { + name: "should reject an IPAddressClaim that doesn't have a cluster name label", + claim: getClaim(func(addr *ipamv1.IPAddressClaim) {}), + expectErr: true, + }, } for i := range tests {