diff --git a/pkg/config/types.go b/pkg/config/types.go index 44682986..7b917087 100644 --- a/pkg/config/types.go +++ b/pkg/config/types.go @@ -11,7 +11,10 @@ const ( NetworkRolePrimary NetworkRole = "primary" ) -const OVNPrimaryNetworkIPAMClaimAnnotation = "k8s.ovn.org/primary-udn-ipamclaim" +const ( + MultusDefaultNetwork = "v1.multus-cni.io/default-network" + DefaultNetworkName = "ovn-kubernetes" +) type RelevantConfig struct { Name string `json:"name"` diff --git a/pkg/ipamclaimswebhook/podmutator.go b/pkg/ipamclaimswebhook/podmutator.go index 9745bcf4..242688e4 100644 --- a/pkg/ipamclaimswebhook/podmutator.go +++ b/pkg/ipamclaimswebhook/podmutator.go @@ -109,7 +109,22 @@ func (a *IPAMClaimsValet) Handle(ctx context.Context, request admission.Request) if newPod == nil { newPod = pod.DeepCopy() } - updatePodWithOVNPrimaryNetworkIPAMClaimAnnotation(newPod, newPrimaryNetworkIPAMClaimName) + + updatePodWithDefaultNetworkAnnotation(newPod) + + nseChanged, updatedNetworkSelectionElements, err := + ensureIPAMClaimRefAtPrimaryNetworkSelectionElements(ctx, a.Client, newPrimaryNetworkIPAMClaimName, networkSelectionElements) + if err != nil { + return admission.Errored(http.StatusInternalServerError, err) + } + if nseChanged { + if newPod == nil { + newPod = pod.DeepCopy() + } + if err := updatePodSelectionElements(newPod, updatedNetworkSelectionElements); err != nil { + return admission.Errored(http.StatusInternalServerError, err) + } + } } if newPod != nil { @@ -159,8 +174,8 @@ func updatePodSelectionElements(pod *corev1.Pod, networks []*v1.NetworkSelection return nil } -func updatePodWithOVNPrimaryNetworkIPAMClaimAnnotation(pod *corev1.Pod, primaryNetworkIPAMClaimName string) { - pod.Annotations[config.OVNPrimaryNetworkIPAMClaimAnnotation] = primaryNetworkIPAMClaimName +func updatePodWithDefaultNetworkAnnotation(pod *corev1.Pod) { + pod.Annotations[config.MultusDefaultNetwork] = "default/" + config.DefaultNetworkName } func ensureIPAMClaimRefAtNetworkSelectionElements(ctx context.Context, @@ -233,12 +248,72 @@ func ensureIPAMClaimRefAtNetworkSelectionElements(ctx context.Context, return hasChangedNetworkSelectionElements, nil } +func ensureIPAMClaimRefAtPrimaryNetworkSelectionElements(ctx context.Context, + cli client.Client, claimName string, + networkSelectionElements []*v1.NetworkSelectionElement) (bool, []*v1.NetworkSelectionElement, error) { + log := logf.FromContext(ctx) + + for i, networkSelectionElement := range networkSelectionElements { + nadName := fmt.Sprintf("%s/%s", networkSelectionElement.Namespace, networkSelectionElement.Name) + if nadName != "default/"+config.DefaultNetworkName { + continue + } + + log.Info("found ovn-kubernetes NAD as part of NSE, checking if update is needed") + nadKey := types.NamespacedName{ + Namespace: networkSelectionElement.Namespace, + Name: networkSelectionElement.Name, + } + + nad := v1.NetworkAttachmentDefinition{} + if err := cli.Get(context.Background(), nadKey, &nad); err != nil { + if k8serrors.IsNotFound(err) { + log.Info("NAD not found, will hang on scheduler", "NAD", nadName) + return false, networkSelectionElements, nil + } + return false, networkSelectionElements, err + } + + pluginConfig, err := config.NewConfig(nad.Spec.Config) + if err != nil { + return false, networkSelectionElements, err + } + + log.Info( + "will request persistent IPs for primary network (via default network)", + "NAD", nadName, + "network", pluginConfig.Name, + ) + + hasChangedNetworkSelectionElements := false + if networkSelectionElements[i].IPAMClaimReference != claimName { + networkSelectionElements[i].IPAMClaimReference = claimName + log.Info( + "requesting claim for primary network via deafult network", + "NAD", nadName, + "network", pluginConfig.Name, + "claim", networkSelectionElement.IPAMClaimReference, + ) + hasChangedNetworkSelectionElements = true + } + return hasChangedNetworkSelectionElements, networkSelectionElements, nil + } + + defaultNetworkNSE := &v1.NetworkSelectionElement{ + Name: config.DefaultNetworkName, + Namespace: "default", + IPAMClaimReference: claimName, + } + networkSelectionElements = append(networkSelectionElements, defaultNetworkNSE) + log.Info("appending NSE for primary network", "defaultNetworkNSE", networkSelectionElements) + + return true, networkSelectionElements, nil +} + func findNewPrimaryNetworkIPAMClaimName(ctx context.Context, cli client.Client, pod *corev1.Pod, vmName string) (string, error) { log := logf.FromContext(ctx) - if pod.Annotations[config.OVNPrimaryNetworkIPAMClaimAnnotation] != "" { - return "", nil - } + primaryNetworkNAD, err := udn.FindPrimaryNetwork(ctx, cli, pod.Namespace) if err != nil { return "", err