Skip to content

Commit 187e06c

Browse files
authored
Merge pull request #5250 from martinkennelly/crash-no-ep
Node port watcher sync: ignore ns with no valid network
2 parents 81d997c + b7c353c commit 187e06c

File tree

4 files changed

+52
-4
lines changed

4 files changed

+52
-4
lines changed

go-controller/pkg/node/gateway_nftables.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,12 @@ func recreateNFTSet(setName string, keepNFTElems []*knftables.Element) error {
122122
tx.Add(elem)
123123
}
124124
}
125-
return nft.Run(context.TODO(), tx)
125+
err = nft.Run(context.TODO(), tx)
126+
// no error if set is not created and we desire zero NFT elements
127+
if knftables.IsNotFound(err) && len(keepNFTElems) == 0 {
128+
return nil
129+
}
130+
return err
126131
}
127132

128133
func recreateNFTMap(mapName string, keepNFTElems []*knftables.Element) error {
@@ -139,7 +144,12 @@ func recreateNFTMap(mapName string, keepNFTElems []*knftables.Element) error {
139144
tx.Add(elem)
140145
}
141146
}
142-
return nft.Run(context.TODO(), tx)
147+
err = nft.Run(context.TODO(), tx)
148+
// no error if set is not created and we desire zero NFT elements
149+
if knftables.IsNotFound(err) && len(keepNFTElems) == 0 {
150+
return nil
151+
}
152+
return err
143153
}
144154

145155
// getGatewayNFTRules returns nftables rules for service. This must be used in conjunction

go-controller/pkg/node/gateway_shared_intf.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,10 @@ func (npw *nodePortWatcher) SyncServices(services []interface{}) error {
10381038
}
10391039

10401040
netInfo, err := npw.networkManager.GetActiveNetworkForNamespace(service.Namespace)
1041+
// The InvalidPrimaryNetworkError is returned when the UDN is not found because it has already been deleted.
1042+
if util.IsInvalidPrimaryNetworkError(err) {
1043+
continue
1044+
}
10411045
if err != nil {
10421046
errors = append(errors, err)
10431047
continue

go-controller/pkg/node/gateway_udn_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import (
4040
ovntest "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/testing"
4141
coreinformermocks "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/testing/mocks/k8s.io/client-go/informers/core/v1"
4242
v1mocks "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/testing/mocks/k8s.io/client-go/listers/core/v1"
43+
fakenetworkmanager "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/testing/networkmanager"
4344
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/types"
4445
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/util"
4546

@@ -1554,6 +1555,34 @@ var _ = Describe("UserDefinedNetworkGateway", func() {
15541555
Expect(err).NotTo(HaveOccurred())
15551556
Expect(fexec.CalledMatchesExpected()).To(BeTrue(), fexec.ErrorDesc)
15561557
})
1558+
1559+
It("should sync node port watcher successfully if a namespaces network is invalid", func() {
1560+
// create new gateway, add ns with primary UDN, pod, expose pod via Node port service, delete pod, delete udn, ensure sync should succeeds
1561+
namespace := util.NewNamespace("udn")
1562+
config.OVNKubernetesFeature.EnableMultiNetwork = true
1563+
config.OVNKubernetesFeature.EnableNetworkSegmentation = true
1564+
namespace.Labels[types.RequiredUDNNamespaceLabel] = ""
1565+
service := newService("udn-svc", namespace.Name, "10.96.0.10", []corev1.ServicePort{{NodePort: int32(30300),
1566+
Protocol: corev1.ProtocolTCP, Port: int32(8080)}}, corev1.ServiceTypeNodePort, []string{}, corev1.ServiceStatus{},
1567+
true, false)
1568+
fakeClient := util.GetOVNClientset(service, namespace)
1569+
wf, err := factory.NewNodeWatchFactory(fakeClient.GetNodeClientset(), "node")
1570+
Expect(err).ToNot(HaveOccurred(), "must get new node watch factory")
1571+
Expect(wf.Start()).NotTo(HaveOccurred(), "must start Node watch factory")
1572+
defer func() {
1573+
wf.Shutdown()
1574+
}()
1575+
iptV4, iptV6 := util.SetFakeIPTablesHelpers()
1576+
nodenft.SetFakeNFTablesHelper()
1577+
fNPW := initFakeNodePortWatcher(iptV4, iptV6)
1578+
fNPW.watchFactory = wf
1579+
// in-order to simulate a namespace with an Invalid UDN (when GetActiveNamespace is called), we add an entry
1580+
// to the fake network manager but no specified network. GetActiveNetwork will return the appropriate error of Invalid Network for namespace.
1581+
// network manager may have a different implementation that fake network manager but both will return the same error.
1582+
fNPW.networkManager = &fakenetworkmanager.FakeNetworkManager{PrimaryNetworks: map[string]util.NetInfo{namespace.Name: nil}}
1583+
services := append([]interface{}{}, service)
1584+
Expect(fNPW.SyncServices(services)).NotTo(HaveOccurred(), "must sync services")
1585+
})
15571586
})
15581587

15591588
func TestConstructUDNVRFIPRules(t *testing.T) {

go-controller/pkg/testing/networkmanager/fake.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ func (fcm *FakeControllerManager) Reconcile(_ string, _, _ util.NetInfo) error {
4646

4747
type FakeNetworkManager struct {
4848
// namespace -> netInfo
49+
// if netInfo is nil, it represents a namespace which contains the required UDN label but with no valid network. It will return invalid network error.
4950
PrimaryNetworks map[string]util.NetInfo
5051
}
5152

@@ -54,11 +55,15 @@ func (fnm *FakeNetworkManager) Start() error { return nil }
5455
func (fnm *FakeNetworkManager) Stop() {}
5556

5657
func (fnm *FakeNetworkManager) GetActiveNetworkForNamespace(namespace string) (util.NetInfo, error) {
57-
return fnm.GetActiveNetworkForNamespaceFast(namespace), nil
58+
network := fnm.GetActiveNetworkForNamespaceFast(namespace)
59+
if network == nil {
60+
return nil, util.NewInvalidPrimaryNetworkError(namespace)
61+
}
62+
return network, nil
5863
}
5964

6065
func (fnm *FakeNetworkManager) GetActiveNetworkForNamespaceFast(namespace string) util.NetInfo {
61-
if primaryNetworks, ok := fnm.PrimaryNetworks[namespace]; ok && primaryNetworks != nil {
66+
if primaryNetworks, ok := fnm.PrimaryNetworks[namespace]; ok {
6267
return primaryNetworks
6368
}
6469
return &util.DefaultNetInfo{}

0 commit comments

Comments
 (0)