Skip to content

Commit d3e489a

Browse files
authored
Merge pull request #5507 from trozet/udn_update_annos_labels
Ensure that UDN update events trigger updates for NAD annotations correctly
2 parents 1497ac3 + d074c6c commit d3e489a

File tree

2 files changed

+71
-1
lines changed

2 files changed

+71
-1
lines changed

go-controller/pkg/clustermanager/userdefinednetwork/controller_helper.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"reflect"
7+
"strings"
78

89
netv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
910

@@ -76,12 +77,24 @@ func (c *Controller) updateNAD(obj client.Object, namespace string) (*netv1.Netw
7677
return nil, fmt.Errorf("foreign NetworkAttachmentDefinition with the desired name already exist [%s/%s]", nadCopy.Namespace, nadCopy.Name)
7778
}
7879

79-
if reflect.DeepEqual(nadCopy.Spec.Config, desiredNAD.Spec.Config) && reflect.DeepEqual(nadCopy.ObjectMeta.Labels, desiredNAD.ObjectMeta.Labels) {
80+
// NAD update path, need to merge internal (k8s.ovn.org) current annotations with desired
81+
for k, v := range nadCopy.Annotations {
82+
if strings.HasPrefix(k, types.OvnK8sPrefix) {
83+
if desiredNAD.Annotations == nil {
84+
desiredNAD.Annotations = make(map[string]string)
85+
}
86+
desiredNAD.Annotations[k] = v
87+
}
88+
}
89+
90+
if reflect.DeepEqual(nadCopy.Spec.Config, desiredNAD.Spec.Config) && reflect.DeepEqual(nadCopy.ObjectMeta.Labels, desiredNAD.ObjectMeta.Labels) &&
91+
reflect.DeepEqual(desiredNAD.Annotations, nadCopy.Annotations) {
8092
return nadCopy, nil
8193
}
8294

8395
nadCopy.Spec.Config = desiredNAD.Spec.Config
8496
nadCopy.ObjectMeta.Labels = desiredNAD.ObjectMeta.Labels
97+
nadCopy.Annotations = desiredNAD.Annotations
8598
updatedNAD, err := c.nadClient.K8sCniCncfIoV1().NetworkAttachmentDefinitions(nadCopy.Namespace).Update(context.Background(), nadCopy, metav1.UpdateOptions{})
8699
if err != nil {
87100
return nil, fmt.Errorf("failed to update NetworkAttachmentDefinition: %w", err)

go-controller/pkg/clustermanager/userdefinednetwork/controller_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,63 @@ var _ = Describe("User Defined Network Controller", func() {
445445
}
446446
})
447447

448+
It("should update NAD annotations and preserve internal OVNK annotations on UDN update", func() {
449+
testNamespaces := []string{"red", "blue"}
450+
var objs []runtime.Object
451+
for _, nsName := range testNamespaces {
452+
objs = append(objs, testNamespace(nsName))
453+
}
454+
cudn := testClusterUDN("test", testNamespaces...)
455+
cudn.Spec.Network = udnv1.NetworkSpec{Topology: udnv1.NetworkTopologyLayer2, Layer2: &udnv1.Layer2Config{
456+
Subnets: udnv1.DualStackCIDRs{"10.10.10.0/24"},
457+
}}
458+
cudn.Annotations = map[string]string{"foo": "bar"}
459+
460+
objs = append(objs, cudn)
461+
networkName := ovntypes.CUDNPrefix + cudn.Name
462+
expectedNsNADs := map[string]*netv1.NetworkAttachmentDefinition{}
463+
for _, nsName := range testNamespaces {
464+
nad := testClusterUdnNAD(cudn.Name, nsName)
465+
nadName := nsName + "/" + cudn.Name
466+
nad.Spec.Config = `{"cniVersion":"1.0.0","name":"` + networkName + `","netAttachDefName":"` + nadName + `","role":"","subnets":"10.10.10.0/24","topology":"layer2","type":"ovn-k8s-cni-overlay"}`
467+
nad.Annotations = map[string]string{
468+
"foo": "bar",
469+
ovntypes.OvnNetworkNameAnnotation: networkName,
470+
ovntypes.OvnNetworkIDAnnotation: "6",
471+
}
472+
expectedNsNADs[nsName] = nad.DeepCopy()
473+
objs = append(objs, nad)
474+
}
475+
476+
c = newTestController(template.RenderNetAttachDefManifest, objs...)
477+
Expect(c.Run()).To(Succeed())
478+
479+
By("updating CUDN with a new annotation")
480+
cudn, err := cs.UserDefinedNetworkClient.K8sV1().ClusterUserDefinedNetworks().Get(context.Background(), cudn.Name, metav1.GetOptions{})
481+
Expect(err).NotTo(HaveOccurred())
482+
updatedCUDN := cudn.DeepCopy()
483+
updatedCUDN.Annotations = map[string]string{"foo2": "bar2"}
484+
_, err = cs.UserDefinedNetworkClient.K8sV1().ClusterUserDefinedNetworks().Update(context.Background(), updatedCUDN, metav1.UpdateOptions{})
485+
Expect(err).NotTo(HaveOccurred())
486+
487+
for testNamespace, expectedNAD := range expectedNsNADs {
488+
expectedNAD.Annotations = map[string]string{
489+
"foo2": "bar2",
490+
ovntypes.OvnNetworkNameAnnotation: networkName,
491+
ovntypes.OvnNetworkIDAnnotation: "6",
492+
}
493+
494+
Eventually(func(g Gomega) {
495+
actualNAD, err := cs.NetworkAttchDefClient.K8sCniCncfIoV1().
496+
NetworkAttachmentDefinitions(testNamespace).
497+
Get(context.Background(), cudn.Name, metav1.GetOptions{})
498+
g.Expect(err).NotTo(HaveOccurred())
499+
g.Expect(actualNAD).To(Equal(expectedNAD), "NAD should exist, have updated "+
500+
"annotations, and preserve internal annotations")
501+
}).Should(Succeed())
502+
}
503+
})
504+
448505
When("CR exist, and few connected & disconnected namespaces", func() {
449506
const (
450507
cudnName = "global-network"

0 commit comments

Comments
 (0)