Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(metallb): remove conflicting IPAddressPools when metallb admission webhook rejects ktf's pool #834

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 21 additions & 8 deletions pkg/clusters/addons/metallb/metallb.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (

"go4.org/netipx"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -43,6 +43,8 @@ const (

addressPoolName = "ktf-pool"
l2AdvertisementName = "ktf-empty"

tickTime = 100 * time.Millisecond
)

var (
Expand Down Expand Up @@ -119,7 +121,7 @@ func (a *addon) Ready(ctx context.Context, cluster clusters.Cluster) ([]runtime.
deployment, err := cluster.Client().AppsV1().Deployments(DefaultNamespace).
Get(ctx, "controller", metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
if apierrors.IsNotFound(err) {
return nil, false, nil
}
return nil, false, err
Expand Down Expand Up @@ -155,7 +157,7 @@ func deployMetallbForKindCluster(ctx context.Context, cluster clusters.Cluster,
// ensure the namespace for metallb is created
ns := corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: DefaultNamespace}}
if _, err := cluster.Client().CoreV1().Namespaces().Create(ctx, &ns, metav1.CreateOptions{}); err != nil {
if !errors.IsAlreadyExists(err) {
if !apierrors.IsAlreadyExists(err) {
return err
}
}
Expand Down Expand Up @@ -190,7 +192,7 @@ func deployMetallbForKindCluster(ctx context.Context, cluster clusters.Cluster,
},
}
if _, err := cluster.Client().CoreV1().Secrets(ns.Name).Create(ctx, secret, metav1.CreateOptions{}); err != nil {
if !errors.IsAlreadyExists(err) {
if !apierrors.IsAlreadyExists(err) {
return err
}
}
Expand Down Expand Up @@ -239,13 +241,24 @@ func createIPAddressPool(ctx context.Context, cluster clusters.Cluster, dockerNe
}, metav1.CreateOptions{})

if err != nil {
if errors.IsAlreadyExists(err) {
if apierrors.IsAlreadyExists(err) {
// delete the existing resource and recreate it in another round of loop.
err = res.Delete(ctx, addressPoolName, metav1.DeleteOptions{})
} else if apierrors.IsForbidden(err) {
// This means most likely that there's a conflicting IPAddressPool
// and we couldn't apply ours. In this case remove the existing pools
// 1 by 1 (most often there's going to be just 1) and re-attempt
// to create a new one.
ipAddressPools, errL := res.List(ctx, metav1.ListOptions{})
if errL != nil {
err = errL
} else if len(ipAddressPools.Items) > 0 {
err = res.Delete(ctx, ipAddressPools.Items[0].GetName(), metav1.DeleteOptions{})
}
}

select {
case <-time.After(time.Second):
case <-time.After(tickTime):
lastErr = err
continue
case <-ctx.Done():
Expand Down Expand Up @@ -282,14 +295,14 @@ func createL2Advertisement(ctx context.Context, cluster clusters.Cluster) error
}, metav1.CreateOptions{})

if err != nil {
if errors.IsAlreadyExists(err) {
if apierrors.IsAlreadyExists(err) {
// delete the existing resource and recreate it in another round of loop.
err = res.Delete(ctx, l2AdvertisementName, metav1.DeleteOptions{})
}

lastErr = err
select {
case <-time.After(time.Second):
case <-time.After(tickTime):
continue
case <-ctx.Done():
return fmt.Errorf("failed to create metallb.io/v1beta1 L2Advertisement: %w, last error %v", ctx.Err(), lastErr)
Expand Down
Loading