Skip to content

Commit 4168c62

Browse files
jaer-tsunJaeryn
and
Jaeryn
authored
test: validate secondary endpoint client failure (#2345)
test: validate secondary endpoint client failure will prevent endpoint creation Co-authored-by: Jaeryn <[email protected]>
1 parent de8f045 commit 4168c62

11 files changed

+90
-28
lines changed

cni/network/invoker_cns.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ func configureSecondaryAddResult(info *IPResultInfo, addResult *IPAMAddResult, p
463463
},
464464
},
465465
},
466-
nicType: cns.DelegatedVMNIC,
466+
nicType: info.nicType,
467467
macAddress: macAddress,
468468
skipDefaultRoutes: info.skipDefaultRoutes,
469469
}

cni/network/network.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,7 @@ func (plugin *NetPlugin) createEndpointInternal(opt *createEndpointInternalOpt)
819819
IPAddresses: addresses,
820820
Routes: routes,
821821
MacAddress: secondaryCniResult.macAddress,
822-
NICType: cns.DelegatedVMNIC,
822+
NICType: secondaryCniResult.nicType,
823823
SkipDefaultRoutes: secondaryCniResult.skipDefaultRoutes,
824824
})
825825
}

netio/mocknetio.go

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"errors"
66
"fmt"
77
"net"
8+
9+
"github.com/Azure/azure-container-networking/netlink"
810
)
911

1012
type getInterfaceValidationFn func(name string) (*net.Interface, error)
@@ -19,7 +21,8 @@ type MockNetIO struct {
1921
// ErrMockNetIOFail - mock netio error
2022
var (
2123
ErrMockNetIOFail = errors.New("netio fail")
22-
hwAddr, _ = net.ParseMAC("ab:cd:ef:12:34:56")
24+
HwAddr, _ = net.ParseMAC("ab:cd:ef:12:34:56")
25+
BadHwAddr, _ = net.ParseMAC("56:34:12:ef:cd:ab")
2326
)
2427

2528
func NewMockNetIO(fail bool, failAttempt int) *MockNetIO {
@@ -48,7 +51,7 @@ func (netshim *MockNetIO) GetNetworkInterfaceByName(name string) (*net.Interface
4851
//nolint:gomnd // Dummy MTU
4952
MTU: 1000,
5053
Name: name,
51-
HardwareAddr: hwAddr,
54+
HardwareAddr: HwAddr,
5255
//nolint:gomnd // Dummy interface index
5356
Index: 2,
5457
}, nil
@@ -59,16 +62,27 @@ func (netshim *MockNetIO) GetNetworkInterfaceAddrs(iface *net.Interface) ([]net.
5962
}
6063

6164
func (netshim *MockNetIO) GetNetworkInterfaceByMac(mac net.HardwareAddr) (*net.Interface, error) {
62-
if !bytes.Equal(mac, hwAddr) {
63-
return nil, fmt.Errorf("%w: %s", ErrMockNetIOFail, mac)
65+
if bytes.Equal(mac, HwAddr) {
66+
return &net.Interface{
67+
//nolint:gomnd // Dummy MTU
68+
MTU: 1000,
69+
Name: "eth1",
70+
HardwareAddr: mac,
71+
//nolint:gomnd // Dummy interface index
72+
Index: 2,
73+
}, nil
6474
}
6575

66-
return &net.Interface{
67-
//nolint:gomnd // Dummy MTU
68-
MTU: 1000,
69-
Name: "eth1",
70-
HardwareAddr: mac,
71-
//nolint:gomnd // Dummy interface index
72-
Index: 2,
73-
}, nil
76+
if bytes.Equal(mac, BadHwAddr) {
77+
return &net.Interface{
78+
//nolint:gomnd // Dummy MTU
79+
MTU: 1000,
80+
Name: netlink.BadEth,
81+
HardwareAddr: mac,
82+
//nolint:gomnd // Dummy interface index
83+
Index: 1,
84+
}, nil
85+
}
86+
87+
return nil, fmt.Errorf("%w: %s", ErrMockNetIOFail, mac)
7488
}

netlink/mocknetlink.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"net"
77
)
88

9+
const BadEth = "badeth"
10+
911
// ErrorMockNetlink - netlink mock error
1012
var ErrorMockNetlink = errors.New("Mock Netlink Error")
1113

@@ -60,7 +62,11 @@ func (f *MockNetlink) SetLinkName(string, string) error {
6062
return f.error()
6163
}
6264

63-
func (f *MockNetlink) SetLinkState(string, bool) error {
65+
func (f *MockNetlink) SetLinkState(name string, _ bool) error {
66+
if name == BadEth {
67+
return ErrorMockNetlink
68+
}
69+
6470
return f.error()
6571
}
6672

network/endpoint.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ func (nw *network) newEndpoint(
157157
}
158158

159159
// DeleteEndpoint deletes an existing endpoint from the network.
160-
func (nw *network) deleteEndpoint(nl netlink.NetlinkInterface, plc platform.ExecClient, nsc NamespaceClientInterface, endpointID string) error {
160+
func (nw *network) deleteEndpoint(nl netlink.NetlinkInterface, plc platform.ExecClient, nioc netio.NetIOInterface, nsc NamespaceClientInterface, endpointID string) error {
161161
var err error
162162

163163
logger.Info("Deleting endpoint from network", zap.String("endpointID", endpointID), zap.String("id", nw.Id))
@@ -176,7 +176,7 @@ func (nw *network) deleteEndpoint(nl netlink.NetlinkInterface, plc platform.Exec
176176

177177
// Call the platform implementation.
178178
// Pass nil for epClient and will be initialized in deleteEndpointImpl
179-
err = nw.deleteEndpointImpl(nl, plc, nil, nsc, ep)
179+
err = nw.deleteEndpointImpl(nl, plc, nil, nioc, nsc, ep)
180180
if err != nil {
181181
return err
182182
}

network/endpoint_linux.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,10 @@ func (nw *network) newEndpointImpl(
157157
epClient = NewLinuxBridgeEndpointClient(nw.extIf, hostIfName, contIfName, nw.Mode, nl, plc)
158158
} else if epInfo.NICType == cns.DelegatedVMNIC {
159159
logger.Info("Secondary client")
160-
epClient = NewSecondaryEndpointClient(nl, plc, nsc, ep)
160+
epClient = NewSecondaryEndpointClient(nl, netioCli, plc, nsc, ep)
161161
} else {
162162
logger.Info("Transparent client")
163-
epClient = NewTransparentEndpointClient(nw.extIf, hostIfName, contIfName, nw.Mode, nl, plc)
163+
epClient = NewTransparentEndpointClient(nw.extIf, hostIfName, contIfName, nw.Mode, nl, netioCli, plc)
164164
}
165165
}
166166

@@ -255,7 +255,7 @@ func (nw *network) newEndpointImpl(
255255
}
256256

257257
// deleteEndpointImpl deletes an existing endpoint from the network.
258-
func (nw *network) deleteEndpointImpl(nl netlink.NetlinkInterface, plc platform.ExecClient, epClient EndpointClient, nsc NamespaceClientInterface, ep *endpoint) error {
258+
func (nw *network) deleteEndpointImpl(nl netlink.NetlinkInterface, plc platform.ExecClient, epClient EndpointClient, nioc netio.NetIOInterface, nsc NamespaceClientInterface, ep *endpoint) error {
259259
// Delete the veth pair by deleting one of the peer interfaces.
260260
// Deleting the host interface is more convenient since it does not require
261261
// entering the container netns and hence works both for CNI and CNM.
@@ -276,13 +276,13 @@ func (nw *network) deleteEndpointImpl(nl netlink.NetlinkInterface, plc platform.
276276
epClient = NewLinuxBridgeEndpointClient(nw.extIf, ep.HostIfName, "", nw.Mode, nl, plc)
277277
} else {
278278
if len(ep.SecondaryInterfaces) > 0 {
279-
epClient = NewSecondaryEndpointClient(nl, plc, nsc, ep)
279+
epClient = NewSecondaryEndpointClient(nl, nioc, plc, nsc, ep)
280280
epClient.DeleteEndpointRules(ep)
281281
//nolint:errcheck // ignore error
282282
epClient.DeleteEndpoints(ep)
283283
}
284284

285-
epClient = NewTransparentEndpointClient(nw.extIf, ep.HostIfName, "", nw.Mode, nl, plc)
285+
epClient = NewTransparentEndpointClient(nw.extIf, ep.HostIfName, "", nw.Mode, nl, nioc, plc)
286286
}
287287
}
288288

network/endpoint_test.go

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,11 +227,11 @@ var _ = Describe("Test Endpoint", func() {
227227
Expect(len(mockCli.endpoints)).To(Equal(1))
228228
// Deleting the endpoint
229229
//nolint:errcheck // ignore error
230-
nw.deleteEndpointImpl(netlink.NewMockNetlink(false, ""), platform.NewMockExecClient(false), mockCli, NewMockNamespaceClient(), ep2)
230+
nw.deleteEndpointImpl(netlink.NewMockNetlink(false, ""), platform.NewMockExecClient(false), mockCli, netio.NewMockNetIO(false, 0), NewMockNamespaceClient(), ep2)
231231
Expect(len(mockCli.endpoints)).To(Equal(0))
232232
// Deleting same endpoint with same id should not fail
233233
//nolint:errcheck // ignore error
234-
nw.deleteEndpointImpl(netlink.NewMockNetlink(false, ""), platform.NewMockExecClient(false), mockCli, NewMockNamespaceClient(), ep2)
234+
nw.deleteEndpointImpl(netlink.NewMockNetlink(false, ""), platform.NewMockExecClient(false), mockCli, netio.NewMockNetIO(false, 0), NewMockNamespaceClient(), ep2)
235235
Expect(len(mockCli.endpoints)).To(Equal(0))
236236
})
237237
})
@@ -262,6 +262,46 @@ var _ = Describe("Test Endpoint", func() {
262262
Expect(ep.Id).To(Equal(epInfo.Id))
263263
})
264264
})
265+
Context("When secondary endpoint client is used", func() {
266+
_, ipnet, _ := net.ParseCIDR("0.0.0.0/0")
267+
nw := &network{
268+
Endpoints: map[string]*endpoint{},
269+
Mode: opModeTransparent,
270+
extIf: &externalInterface{BridgeName: "testbridge"},
271+
}
272+
epInfo := &EndpointInfo{
273+
Id: "768e8deb-eth1",
274+
IfName: eth0IfName,
275+
NICType: cns.InfraNIC,
276+
}
277+
secondaryEpInfo := &EndpointInfo{
278+
NICType: cns.DelegatedVMNIC,
279+
Routes: []RouteInfo{{Dst: *ipnet}},
280+
}
281+
282+
It("Should not endpoint to the network when there is an error", func() {
283+
secondaryEpInfo.MacAddress = netio.BadHwAddr // mock netlink will fail to set link state on bad eth
284+
ep, err := nw.newEndpointImpl(nil, netlink.NewMockNetlink(false, ""), platform.NewMockExecClient(false),
285+
netio.NewMockNetIO(false, 0), nil, NewMockNamespaceClient(), []*EndpointInfo{epInfo, secondaryEpInfo})
286+
Expect(err).To(HaveOccurred())
287+
Expect(err.Error()).To(Equal("SecondaryEndpointClient Error: " + netlink.ErrorMockNetlink.Error()))
288+
Expect(ep).To(BeNil())
289+
290+
secondaryEpInfo.MacAddress = netio.HwAddr
291+
ep, err = nw.newEndpointImpl(nil, netlink.NewMockNetlink(false, ""), platform.NewMockExecClient(false),
292+
netio.NewMockNetIO(false, 0), nil, NewMockNamespaceClient(), []*EndpointInfo{epInfo, secondaryEpInfo})
293+
Expect(err).ToNot(HaveOccurred())
294+
Expect(ep.Id).To(Equal(epInfo.Id))
295+
})
296+
297+
It("Should add endpoint when there are no errors", func() {
298+
secondaryEpInfo.MacAddress = netio.HwAddr
299+
ep, err := nw.newEndpointImpl(nil, netlink.NewMockNetlink(false, ""), platform.NewMockExecClient(false),
300+
netio.NewMockNetIO(false, 0), nil, NewMockNamespaceClient(), []*EndpointInfo{epInfo, secondaryEpInfo})
301+
Expect(err).ToNot(HaveOccurred())
302+
Expect(ep.Id).To(Equal(epInfo.Id))
303+
})
304+
})
265305
})
266306

267307
Describe("Test updateEndpoint", func() {

network/endpoint_windows.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ func (nw *network) newEndpointImplHnsV2(cli apipaClient, epInfo *EndpointInfo) (
409409
}
410410

411411
// deleteEndpointImpl deletes an existing endpoint from the network.
412-
func (nw *network) deleteEndpointImpl(_ netlink.NetlinkInterface, _ platform.ExecClient, _ EndpointClient, _ NamespaceClientInterface, ep *endpoint) error {
412+
func (nw *network) deleteEndpointImpl(_ netlink.NetlinkInterface, _ platform.ExecClient, _ EndpointClient, _ netio.NetIOInterface, _ NamespaceClientInterface, ep *endpoint) error {
413413
if useHnsV2, err := UseHnsV2(ep.NetNs); useHnsV2 {
414414
if err != nil {
415415
return err

network/manager.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ func (nm *networkManager) DeleteEndpoint(networkID, endpointID string) error {
369369
return err
370370
}
371371

372-
err = nw.deleteEndpoint(nm.netlink, nm.plClient, nm.nsClient, endpointID)
372+
err = nw.deleteEndpoint(nm.netlink, nm.plClient, nm.netio, nm.nsClient, endpointID)
373373
if err != nil {
374374
return err
375375
}

network/secondary_endpoint_client_linux.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,14 @@ type SecondaryEndpointClient struct {
3030

3131
func NewSecondaryEndpointClient(
3232
nl netlink.NetlinkInterface,
33+
nioc netio.NetIOInterface,
3334
plc platform.ExecClient,
3435
nsc NamespaceClientInterface,
3536
endpoint *endpoint,
3637
) *SecondaryEndpointClient {
3738
client := &SecondaryEndpointClient{
3839
netlink: nl,
39-
netioshim: &netio.NetIO{},
40+
netioshim: nioc,
4041
plClient: plc,
4142
netUtilsClient: networkutils.NewNetworkUtils(nl, plc),
4243
nsClient: nsc,

network/transparent_endpointclient_linux.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ func NewTransparentEndpointClient(
5252
containerVethName string,
5353
mode string,
5454
nl netlink.NetlinkInterface,
55+
nioc netio.NetIOInterface,
5556
plc platform.ExecClient,
5657
) *TransparentEndpointClient {
5758
client := &TransparentEndpointClient{
@@ -62,7 +63,7 @@ func NewTransparentEndpointClient(
6263
hostPrimaryMac: extIf.MacAddress,
6364
mode: mode,
6465
netlink: nl,
65-
netioshim: &netio.NetIO{},
66+
netioshim: nioc,
6667
plClient: plc,
6768
netUtilsClient: networkutils.NewNetworkUtils(nl, plc),
6869
}

0 commit comments

Comments
 (0)