Skip to content

Commit 7a3232c

Browse files
authored
fix e2e vlan interface (#6036)
Signed-off-by: clyi <clyi@alauda.io>
1 parent 76bbf44 commit 7a3232c

File tree

1 file changed

+133
-56
lines changed

1 file changed

+133
-56
lines changed

test/e2e/kube-ovn/underlay/vlan_subinterfaces.go

Lines changed: 133 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ var _ = framework.SerialDescribe("[group:underlay]", func() {
2929
var kindNodes []kind.Node
3030
var dockerNetwork *dockernetwork.Inspect
3131
var dockerNetworkName string
32-
var baseInterface string
33-
var customInterfaces map[string][]string
32+
var pnDefaultParentInterface string // interface name (on the first node) for the test docker network; used as the default
33+
var nodeInterfaces map[string]string // actual interface name per node for the test docker network, keyed by node name
3434

3535
ginkgo.BeforeEach(func() {
3636
providerNetworkClient = f.ProviderNetworkClient()
@@ -53,9 +53,11 @@ var _ = framework.SerialDescribe("[group:underlay]", func() {
5353
framework.ExpectNotEmpty(kindNodes)
5454

5555
dockerNetworkName = "vlan-subif-" + framework.RandomSuffix()[:6]
56+
ginkgo.By(fmt.Sprintf("Creating docker network %s", dockerNetworkName))
5657
dockerNetwork, err = docker.NetworkCreate(dockerNetworkName, true, true)
5758
framework.ExpectNoError(err, "creating docker network "+dockerNetworkName)
5859

60+
ginkgo.By(fmt.Sprintf("Connecting nodes to docker network %s", dockerNetworkName))
5961
err = kind.NetworkConnect(dockerNetwork.ID, kindNodes)
6062
framework.ExpectNoError(err, "connecting nodes to network "+dockerNetworkName)
6163

@@ -69,7 +71,7 @@ var _ = framework.SerialDescribe("[group:underlay]", func() {
6971
readySet[readyNodes.Items[i].Name] = struct{}{}
7072
}
7173

72-
ifaceMap := make(map[string]string, len(kindNodes))
74+
nodeInterfaces = make(map[string]string, len(kindNodes))
7375
for i := range kindNodes {
7476
node := kindNodes[i]
7577
kindNodeMap[node.Name()] = node
@@ -82,46 +84,58 @@ var _ = framework.SerialDescribe("[group:underlay]", func() {
8284
mac := node.NetworkSettings.Networks[dockerNetworkName].MacAddress.String()
8385
for _, link := range links {
8486
if link.Address == mac {
85-
ifaceMap[node.Name()] = link.IfName
87+
nodeInterfaces[node.Name()] = link.IfName
8688
break
8789
}
8890
}
89-
framework.ExpectHaveKey(ifaceMap, node.Name(), "expected interface for node %s in network %s", node.Name(), dockerNetworkName)
91+
framework.ExpectHaveKey(nodeInterfaces, node.Name(), "expected interface for node %s in network %s", node.Name(), dockerNetworkName)
9092
}
9193

92-
baseInterface = ifaceMap[kindNodes[0].Name()]
93-
customInterfaces = make(map[string][]string)
94-
for name, ifName := range ifaceMap {
95-
if ifName != baseInterface {
96-
customInterfaces[ifName] = append(customInterfaces[ifName], name)
97-
}
98-
}
94+
pnDefaultParentInterface = nodeInterfaces[kindNodes[0].Name()]
9995
})
10096

10197
ginkgo.AfterEach(func() {
10298
for i := len(providerNetworkNames) - 1; i >= 0; i-- {
10399
providerNetworkClient.DeleteSync(providerNetworkNames[i])
104100
}
105101
if dockerNetwork != nil {
106-
_ = kind.NetworkDisconnect(dockerNetwork.ID, kindNodes)
107-
_ = docker.NetworkRemove(dockerNetwork.ID)
102+
ginkgo.By(fmt.Sprintf("Disconnecting nodes from docker network %s", dockerNetworkName))
103+
framework.ExpectNoError(kind.NetworkDisconnect(dockerNetwork.ID, kindNodes))
104+
105+
ginkgo.By(fmt.Sprintf("Removing docker network %s", dockerNetworkName))
106+
framework.ExpectNoError(docker.NetworkRemove(dockerNetwork.ID))
107+
108+
ginkgo.By(fmt.Sprintf("Waiting for docker network %s to disappear", dockerNetworkName))
109+
framework.WaitUntil(2*time.Second, 30*time.Second, func(_ context.Context) (bool, error) {
110+
_, err := docker.NetworkInspect(dockerNetworkName)
111+
if err != nil {
112+
if strings.Contains(err.Error(), "does not exist") {
113+
return true, nil
114+
}
115+
return false, err
116+
}
117+
return false, nil
118+
}, fmt.Sprintf("docker network %s removal", dockerNetworkName))
108119
}
109120
})
110121

111122
framework.ConformanceIt(`should create vlan subinterface when autoCreateVlanSubinterfaces is true`, func() {
112123
f.SkipVersionPriorTo(1, 15, "vlan subinterfaces are not supported before 1.15.0")
113124
providerNetworkName := allocProviderNetworkName()
114-
interfaceName := baseInterface + ".100"
125+
pnDefaultInterface := pnDefaultParentInterface + ".100" // VLAN interface we expect to manage (physical interface + VLAN ID)
126+
vlanID := extractVlanID(pnDefaultInterface)
115127

116-
pn := createVlanSubinterfaceTestProviderNetwork(providerNetworkName, interfaceName, true, customInterfaces)
128+
customInterfaces := makeCustomInterfaceMap(vlanID, nodeInterfaces)
129+
pn := createVlanSubinterfaceTestProviderNetwork(providerNetworkName, pnDefaultInterface, true, customInterfaces)
117130
providerNetworkClient.CreateSync(pn)
118131

119132
framework.ExpectTrue(providerNetworkClient.WaitToBeReady(providerNetworkName, time.Minute))
120133

121134
for _, node := range readyKindNodes {
122135
nodeName := node.Name()
123-
framework.ExpectTrue(vlanSubinterfaceExists(kindNodeMap, nodeName, interfaceName), fmt.Sprintf("VLAN subinterface %s should exist on node %s", interfaceName, nodeName))
124-
framework.ExpectTrue(isKubeOVNAutoCreatedInterface(kindNodeMap, nodeName, interfaceName), fmt.Sprintf("VLAN subinterface %s should be created by Kube-OVN on node %s", interfaceName, nodeName))
136+
nodeIface := nodeInterfaceNameFor(nodeName, pnDefaultInterface, nodeInterfaces)
137+
framework.ExpectTrue(vlanSubinterfaceExists(kindNodeMap, nodeName, nodeIface), fmt.Sprintf("VLAN subinterface %s should exist on node %s", nodeIface, nodeName))
138+
framework.ExpectTrue(isKubeOVNAutoCreatedInterface(kindNodeMap, nodeName, nodeIface), fmt.Sprintf("VLAN subinterface %s should be created by Kube-OVN on node %s", nodeIface, nodeName))
125139
}
126140

127141
providerNetworkClient.DeleteSync(providerNetworkName)
@@ -130,18 +144,24 @@ var _ = framework.SerialDescribe("[group:underlay]", func() {
130144
framework.ConformanceIt(`should isolate subinterfaces across multiple provider networks`, func() {
131145
f.SkipVersionPriorTo(1, 15, "vlan subinterfaces are not supported before 1.15.0")
132146
pn1Name := allocProviderNetworkName()
133-
pn1Interface := baseInterface + ".100"
134-
pn1 := createVlanSubinterfaceTestProviderNetwork(pn1Name, pn1Interface, true, customInterfaces)
147+
pn1Interface := pnDefaultParentInterface + ".100"
148+
pn1VlanID := extractVlanID(pn1Interface)
149+
customPn1Interfaces := makeCustomInterfaceMap(pn1VlanID, nodeInterfaces)
150+
pn1 := createVlanSubinterfaceTestProviderNetwork(pn1Name, pn1Interface, true, customPn1Interfaces)
135151
providerNetworkClient.CreateSync(pn1)
136152

137153
pn2Name := allocProviderNetworkName()
138-
pn2Interface := baseInterface
139-
pn2 := createVlanSubinterfaceTestProviderNetwork(pn2Name, pn2Interface, false, customInterfaces)
154+
pn2Interface := pnDefaultParentInterface
155+
pn2VlanID := extractVlanID(pn2Interface)
156+
customPn2Interfaces := makeCustomInterfaceMap(pn2VlanID, nodeInterfaces)
157+
pn2 := createVlanSubinterfaceTestProviderNetwork(pn2Name, pn2Interface, false, customPn2Interfaces)
140158
providerNetworkClient.CreateSync(pn2)
141159

142160
pn3Name := allocProviderNetworkName()
143-
pn3Interface := baseInterface + ".300"
144-
pn3 := createVlanSubinterfaceTestProviderNetwork(pn3Name, pn3Interface, true, customInterfaces)
161+
pn3Interface := pnDefaultParentInterface + ".300"
162+
pn3VlanID := extractVlanID(pn3Interface)
163+
customPn3Interfaces := makeCustomInterfaceMap(pn3VlanID, nodeInterfaces)
164+
pn3 := createVlanSubinterfaceTestProviderNetwork(pn3Name, pn3Interface, true, customPn3Interfaces)
145165
providerNetworkClient.CreateSync(pn3)
146166

147167
framework.ExpectTrue(providerNetworkClient.WaitToBeReady(pn1Name, time.Minute))
@@ -150,21 +170,26 @@ var _ = framework.SerialDescribe("[group:underlay]", func() {
150170

151171
for _, node := range readyKindNodes {
152172
nodeName := node.Name()
153-
framework.ExpectTrue(vlanSubinterfaceExists(kindNodeMap, nodeName, pn1Interface), fmt.Sprintf("VLAN subinterface %s should exist on node %s", pn1Interface, nodeName))
154-
framework.ExpectTrue(isKubeOVNAutoCreatedInterface(kindNodeMap, nodeName, pn1Interface), fmt.Sprintf("VLAN subinterface %s should be created by Kube-OVN on node %s", pn1Interface, nodeName))
173+
nodePn1Interface := nodeInterfaceNameFor(nodeName, pn1Interface, nodeInterfaces)
174+
framework.ExpectTrue(vlanSubinterfaceExists(kindNodeMap, nodeName, nodePn1Interface), fmt.Sprintf("VLAN subinterface %s should exist on node %s", nodePn1Interface, nodeName))
175+
framework.ExpectTrue(isKubeOVNAutoCreatedInterface(kindNodeMap, nodeName, nodePn1Interface), fmt.Sprintf("VLAN subinterface %s should be created by Kube-OVN on node %s", nodePn1Interface, nodeName))
155176

156-
framework.ExpectFalse(isKubeOVNAutoCreatedInterface(kindNodeMap, nodeName, pn2Interface), fmt.Sprintf("Base interface %s on node %s should not be modified by Kube-OVN when autoCreateVlanSubinterfaces is false", pn2Interface, nodeName))
177+
nodePn2Interface := nodeInterfaceNameFor(nodeName, pn2Interface, nodeInterfaces)
178+
framework.ExpectFalse(isKubeOVNAutoCreatedInterface(kindNodeMap, nodeName, nodePn2Interface), fmt.Sprintf("Base interface %s on node %s should not be modified by Kube-OVN when autoCreateVlanSubinterfaces is false", nodePn2Interface, nodeName))
157179

158-
framework.ExpectTrue(vlanSubinterfaceExists(kindNodeMap, nodeName, pn3Interface), fmt.Sprintf("VLAN subinterface %s should exist on node %s", pn3Interface, nodeName))
159-
framework.ExpectTrue(isKubeOVNAutoCreatedInterface(kindNodeMap, nodeName, pn3Interface), fmt.Sprintf("VLAN subinterface %s should be created by Kube-OVN on node %s", pn3Interface, nodeName))
180+
nodePn3Interface := nodeInterfaceNameFor(nodeName, pn3Interface, nodeInterfaces)
181+
framework.ExpectTrue(vlanSubinterfaceExists(kindNodeMap, nodeName, nodePn3Interface), fmt.Sprintf("VLAN subinterface %s should exist on node %s", nodePn3Interface, nodeName))
182+
framework.ExpectTrue(isKubeOVNAutoCreatedInterface(kindNodeMap, nodeName, nodePn3Interface), fmt.Sprintf("VLAN subinterface %s should be created by Kube-OVN on node %s", nodePn3Interface, nodeName))
160183
}
161184

162185
providerNetworkClient.DeleteSync(pn1Name)
163186

164187
for _, node := range readyKindNodes {
165188
nodeName := node.Name()
166-
waitForInterfaceState(kindNodeMap, nodeName, pn1Interface, false, 2*time.Minute)
167-
framework.ExpectTrue(vlanSubinterfaceExists(kindNodeMap, nodeName, pn3Interface), fmt.Sprintf("VLAN subinterface %s should still exist on node %s", pn3Interface, nodeName))
189+
nodePn1Interface := nodeInterfaceNameFor(nodeName, pn1Interface, nodeInterfaces)
190+
waitForInterfaceState(kindNodeMap, nodeName, nodePn1Interface, false, 2*time.Minute)
191+
nodePn3Interface := nodeInterfaceNameFor(nodeName, pn3Interface, nodeInterfaces)
192+
framework.ExpectTrue(vlanSubinterfaceExists(kindNodeMap, nodeName, nodePn3Interface), fmt.Sprintf("VLAN subinterface %s should still exist on node %s", nodePn3Interface, nodeName))
168193
}
169194

170195
providerNetworkClient.DeleteSync(pn2Name)
@@ -174,40 +199,47 @@ var _ = framework.SerialDescribe("[group:underlay]", func() {
174199
framework.ConformanceIt(`should cleanup auto-created subinterfaces when provider network is deleted`, func() {
175200
f.SkipVersionPriorTo(1, 15, "vlan subinterfaces are not supported before 1.15.0")
176201
providerNetworkName := allocProviderNetworkName()
177-
interfaceName := baseInterface + ".100"
202+
pnDefaultInterface := pnDefaultParentInterface + ".100"
203+
vlanID := extractVlanID(pnDefaultInterface)
178204

179-
pn := createVlanSubinterfaceTestProviderNetwork(providerNetworkName, interfaceName, true, customInterfaces)
205+
customInterfaces := makeCustomInterfaceMap(vlanID, nodeInterfaces)
206+
pn := createVlanSubinterfaceTestProviderNetwork(providerNetworkName, pnDefaultInterface, true, customInterfaces)
180207
providerNetworkClient.CreateSync(pn)
181208

182209
framework.ExpectTrue(providerNetworkClient.WaitToBeReady(providerNetworkName, time.Minute))
183210

184211
for _, node := range readyKindNodes {
185212
nodeName := node.Name()
186-
framework.ExpectTrue(vlanSubinterfaceExists(kindNodeMap, nodeName, interfaceName), fmt.Sprintf("VLAN subinterface %s should exist on node %s", interfaceName, nodeName))
187-
framework.ExpectTrue(isKubeOVNAutoCreatedInterface(kindNodeMap, nodeName, interfaceName), fmt.Sprintf("VLAN subinterface %s should be created by Kube-OVN on node %s", interfaceName, nodeName))
213+
nodeIface := nodeInterfaceNameFor(nodeName, pnDefaultInterface, nodeInterfaces)
214+
framework.ExpectTrue(vlanSubinterfaceExists(kindNodeMap, nodeName, nodeIface), fmt.Sprintf("VLAN subinterface %s should exist on node %s", nodeIface, nodeName))
215+
framework.ExpectTrue(isKubeOVNAutoCreatedInterface(kindNodeMap, nodeName, nodeIface), fmt.Sprintf("VLAN subinterface %s should be created by Kube-OVN on node %s", nodeIface, nodeName))
188216
}
189217

190218
providerNetworkClient.DeleteSync(providerNetworkName)
191219

192220
for _, node := range readyKindNodes {
193-
waitForInterfaceState(kindNodeMap, node.Name(), interfaceName, false, 2*time.Minute)
221+
nodeIface := nodeInterfaceNameFor(node.Name(), pnDefaultInterface, nodeInterfaces)
222+
waitForInterfaceState(kindNodeMap, node.Name(), nodeIface, false, 2*time.Minute)
194223
}
195224
})
196225

197226
framework.ConformanceIt(`should not cleanup existing subinterfaces when autoCreateVlanSubinterfaces set to false`, func() {
198227
f.SkipVersionPriorTo(1, 15, "vlan subinterfaces are not supported before 1.15.0")
199228
providerNetworkName := allocProviderNetworkName()
200-
interfaceName := baseInterface + ".100"
229+
pnDefaultInterface := pnDefaultParentInterface + ".100"
230+
vlanID := extractVlanID(pnDefaultInterface)
201231

202-
pn := createVlanSubinterfaceTestProviderNetwork(providerNetworkName, interfaceName, true, customInterfaces)
232+
customInterfaces := makeCustomInterfaceMap(vlanID, nodeInterfaces)
233+
pn := createVlanSubinterfaceTestProviderNetwork(providerNetworkName, pnDefaultInterface, true, customInterfaces)
203234
pn = providerNetworkClient.CreateSync(pn)
204235

205236
framework.ExpectTrue(providerNetworkClient.WaitToBeReady(providerNetworkName, time.Minute))
206237

207238
for _, node := range readyKindNodes {
208239
nodeName := node.Name()
209-
framework.ExpectTrue(vlanSubinterfaceExists(kindNodeMap, nodeName, interfaceName), fmt.Sprintf("VLAN subinterface %s should exist on node %s", interfaceName, nodeName))
210-
framework.ExpectTrue(isKubeOVNAutoCreatedInterface(kindNodeMap, nodeName, interfaceName), fmt.Sprintf("VLAN subinterface %s should be created by Kube-OVN on node %s", interfaceName, nodeName))
240+
nodeIface := nodeInterfaceNameFor(nodeName, pnDefaultInterface, nodeInterfaces)
241+
framework.ExpectTrue(vlanSubinterfaceExists(kindNodeMap, nodeName, nodeIface), fmt.Sprintf("VLAN subinterface %s should exist on node %s", nodeIface, nodeName))
242+
framework.ExpectTrue(isKubeOVNAutoCreatedInterface(kindNodeMap, nodeName, nodeIface), fmt.Sprintf("VLAN subinterface %s should be created by Kube-OVN on node %s", nodeIface, nodeName))
211243
}
212244

213245
original := pn.DeepCopy()
@@ -216,30 +248,34 @@ var _ = framework.SerialDescribe("[group:underlay]", func() {
216248
framework.ExpectTrue(providerNetworkClient.WaitToBeReady(providerNetworkName, time.Minute))
217249

218250
for _, node := range readyKindNodes {
251+
nodeIface := nodeInterfaceNameFor(node.Name(), pnDefaultInterface, nodeInterfaces)
219252
time.Sleep(5 * time.Second)
220-
framework.ExpectTrue(vlanSubinterfaceExists(kindNodeMap, node.Name(), interfaceName), fmt.Sprintf("VLAN subinterface %s should still exist on node %s when autoCreateVlanSubinterfaces is false", interfaceName, node.Name()))
253+
framework.ExpectTrue(vlanSubinterfaceExists(kindNodeMap, node.Name(), nodeIface), fmt.Sprintf("VLAN subinterface %s should still exist on node %s when autoCreateVlanSubinterfaces is false", nodeIface, node.Name()))
221254
}
222255

223256
providerNetworkClient.DeleteSync(providerNetworkName)
224257
})
225258

226-
framework.ConformanceIt(`should handle edge cases properly`, func() {
259+
framework.ConformanceIt(`should handle subinterfaces edge cases properly`, func() {
227260
f.SkipVersionPriorTo(1, 15, "vlan subinterfaces are not supported before 1.15.0")
228261
ginkgo.By("should not create subinterface for non-VLAN interface name")
229262
{
230263
providerNetworkName := allocProviderNetworkName()
231-
interfaceName := baseInterface
264+
pnDefaultInterface := pnDefaultParentInterface
265+
vlanID := extractVlanID(pnDefaultInterface)
232266

233-
pn := createVlanSubinterfaceTestProviderNetwork(providerNetworkName, interfaceName, true, customInterfaces)
267+
customInterfaces := makeCustomInterfaceMap(vlanID, nodeInterfaces)
268+
pn := createVlanSubinterfaceTestProviderNetwork(providerNetworkName, pnDefaultInterface, true, customInterfaces)
234269
providerNetworkClient.CreateSync(pn)
235270

236271
framework.ExpectTrue(providerNetworkClient.WaitToBeReady(providerNetworkName, time.Minute))
237272

238273
for _, node := range readyKindNodes {
239274
nodeName := node.Name()
240-
exists := vlanSubinterfaceExists(kindNodeMap, nodeName, interfaceName)
275+
nodeIface := nodeInterfaceNameFor(nodeName, pnDefaultInterface, nodeInterfaces)
276+
exists := vlanSubinterfaceExists(kindNodeMap, nodeName, nodeIface)
241277
if exists {
242-
framework.ExpectFalse(isKubeOVNAutoCreatedInterface(kindNodeMap, nodeName, interfaceName), fmt.Sprintf("Interface %s on node %s should not be a Kube-OVN created subinterface", interfaceName, nodeName))
278+
framework.ExpectFalse(isKubeOVNAutoCreatedInterface(kindNodeMap, nodeName, nodeIface), fmt.Sprintf("Interface %s on node %s should not be a Kube-OVN created subinterface", nodeIface, nodeName))
243279
}
244280
}
245281

@@ -248,28 +284,69 @@ var _ = framework.SerialDescribe("[group:underlay]", func() {
248284
})
249285
})
250286

251-
func createVlanSubinterfaceTestProviderNetwork(name, interfaceName string, autoCreate bool, customInterfaces map[string][]string) *v1.ProviderNetwork {
252-
customIfs := make([]v1.CustomInterface, 0, len(customInterfaces))
253-
for ifName, nodes := range customInterfaces {
254-
customIfs = append(customIfs, v1.CustomInterface{
255-
Interface: ifName,
256-
Nodes: nodes,
257-
})
258-
}
259-
287+
func createVlanSubinterfaceTestProviderNetwork(name, defaultInterface string, autoCreate bool, customInterfaces map[string][]string) *v1.ProviderNetwork {
288+
customIfs := buildCustomInterfaces(customInterfaces)
260289
return &v1.ProviderNetwork{
261290
ObjectMeta: metav1.ObjectMeta{
262291
Name: name,
263292
},
264293
Spec: v1.ProviderNetworkSpec{
265-
DefaultInterface: interfaceName,
294+
DefaultInterface: defaultInterface,
266295
AutoCreateVlanSubinterfaces: autoCreate,
267296
ExchangeLinkName: false,
268297
CustomInterfaces: customIfs,
269298
},
270299
}
271300
}
272301

302+
func buildCustomInterfaces(customInterfaceNodes map[string][]string) []v1.CustomInterface {
303+
customIfs := make([]v1.CustomInterface, 0, len(customInterfaceNodes))
304+
for ifName, nodes := range customInterfaceNodes {
305+
customIfs = append(customIfs, v1.CustomInterface{
306+
Interface: ifName,
307+
Nodes: nodes,
308+
})
309+
}
310+
return customIfs
311+
}
312+
313+
// makeCustomInterfaceMap builds customInterfaces based on the VLAN ID and each node's actual interface name.
314+
func makeCustomInterfaceMap(vlanID string, nodeInterfaces map[string]string) map[string][]string {
315+
customInterfaceNodes := make(map[string][]string, len(nodeInterfaces))
316+
for nodeName, nodeIface := range nodeInterfaces {
317+
perNodeInterface := buildNodeInterfaceName(nodeIface, vlanID)
318+
customInterfaceNodes[perNodeInterface] = append(customInterfaceNodes[perNodeInterface], nodeName)
319+
}
320+
321+
return customInterfaceNodes
322+
}
323+
324+
func nodeInterfaceNameFor(nodeName, targetInterface string, nodeInterfaces map[string]string) string {
325+
if nodeInterfaces == nil {
326+
return targetInterface
327+
}
328+
iface, ok := nodeInterfaces[nodeName]
329+
if !ok {
330+
return targetInterface
331+
}
332+
vlanID := extractVlanID(targetInterface)
333+
return buildNodeInterfaceName(iface, vlanID)
334+
}
335+
336+
func buildNodeInterfaceName(nodeInterface, vlanID string) string {
337+
if vlanID == "" {
338+
return nodeInterface
339+
}
340+
return nodeInterface + "." + vlanID
341+
}
342+
343+
func extractVlanID(interfaceName string) string {
344+
if idx := strings.Index(interfaceName, "."); idx != -1 && idx+1 < len(interfaceName) {
345+
return interfaceName[idx+1:]
346+
}
347+
return ""
348+
}
349+
273350
func waitForInterfaceState(nodeExecMap map[string]kind.Node, nodeName, interfaceName string, expected bool, timeout time.Duration) {
274351
ginkgo.GinkgoHelper()
275352

0 commit comments

Comments
 (0)