diff --git a/pkg/webhook/shoot/add.go b/pkg/webhook/shoot/add.go index e3fed946..fe2ed840 100644 --- a/pkg/webhook/shoot/add.go +++ b/pkg/webhook/shoot/add.go @@ -25,6 +25,7 @@ func AddToManagerWithOptions(mgr manager.Manager, opts AddOptions) (*extensionsw return shoot.New(mgr, shoot.Args{ Types: []extensionswebhook.Type{ {Obj: &appsv1.Deployment{}}, + {Obj: &appsv1.DaemonSet{}}, {Obj: &corev1.ConfigMap{}}, {Obj: &corev1.Secret{}}, }, diff --git a/pkg/webhook/shoot/mutator.go b/pkg/webhook/shoot/mutator.go index 9cac9c02..8fcedb7f 100644 --- a/pkg/webhook/shoot/mutator.go +++ b/pkg/webhook/shoot/mutator.go @@ -3,6 +3,8 @@ package shoot import ( "context" "fmt" + "slices" + "strconv" extensionswebhook "github.com/gardener/gardener/extensions/pkg/webhook" @@ -48,6 +50,13 @@ func (m *mutator) Mutate(ctx context.Context, new, _ client.Object) error { case "vpn-shoot": extensionswebhook.LogMutation(logger, x.Kind, x.Namespace, x.Name) return m.mutateVPNShootDeployment(ctx, x) + + } + case *appsv1.DaemonSet: + switch x.Name { + case "calico-node": + extensionswebhook.LogMutation(logger, x.Kind, x.Namespace, x.Name) + return m.mutateCalicoNode(ctx, x) } } return nil @@ -59,7 +68,7 @@ func (m *mutator) mutateVPNShootDeployment(_ context.Context, deployment *appsv1 // raising the timeout to 15 minutes leads to additional 15 minutes of provisioning time because // the nodes cidr will only be set on next shoot reconcile // with the following mutation we can immediately provide the proper nodes cidr and save time - logger.Info("ensuring nodes cidr from shoot-node-cidr configmap in vpn-shoot deployment") + m.logger.Info("ensuring nodes cidr from shoot-node-cidr configmap in vpn-shoot deployment") c.Env = extensionswebhook.EnsureEnvVarWithName(c.Env, corev1.EnvVar{ Name: "NODE_NETWORK", Value: "", @@ -76,3 +85,42 @@ func (m *mutator) mutateVPNShootDeployment(_ context.Context, deployment *appsv1 return nil } + +func (m *mutator) mutateCalicoNode(_ context.Context, ds *appsv1.DaemonSet) error { + if c := extensionswebhook.ContainerWithName(ds.Spec.Template.Spec.Containers, "calico-node"); c != nil { + ebpfEnabled := slices.ContainsFunc(c.Env, func(e corev1.EnvVar) bool { + if e.Name != "FELIX_BPFENABLED" { + return false + } + + enabled, _ := strconv.ParseBool(e.Value) + + return enabled + }) + + if !ebpfEnabled { + return nil + } + + m.logger.Info("patching calico-node daemon set due to ebpf dataplane being enabled") + + c.Env = extensionswebhook.EnsureEnvVarWithName(c.Env, corev1.EnvVar{ + Name: "FELIX_BPFDATAIFACEPATTERN", + // including "lan" interface name to default value + // (see https://github.com/projectcalico/calico/blob/3f7fe4d290541bbdd73c97bdc89a29a29855a48a/felix/config/config_params.go#L180) + Value: "^((en|wl|ww|sl|ib)[Popsx].*|(lan|eth|wlan|wwan).*|tunl0$|vxlan.calico$|wireguard.cali$|wg-v6.cali$)", + }) + + c.Env = extensionswebhook.EnsureEnvVarWithName(c.Env, corev1.EnvVar{ + Name: "FELIX_BPFEXTERNALSERVICEMODE", + Value: "DSR", + }) + + c.Env = extensionswebhook.EnsureEnvVarWithName(c.Env, corev1.EnvVar{ + Name: "FELIX_MTUIFACEPATTERN", + Value: "lan", + }) + } + + return nil +}