Skip to content

Commit 6e6c0aa

Browse files
committed
ci: fix non-primary cni e2e test
Signed-off-by: zhangzujian <[email protected]>
1 parent 9223fa2 commit 6e6c0aa

File tree

6 files changed

+132
-144
lines changed

6 files changed

+132
-144
lines changed

.github/workflows/build-x86-image.yaml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,9 +1502,11 @@ jobs:
15021502
run: docker load -i kube-ovn.tar
15031503

15041504
- name: Create kind cluster
1505+
env:
1506+
GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
15051507
run: |
15061508
pipx install jinjanator
1507-
make kind-init-${{ matrix.ip-family }}
1509+
make kind-ghcr-pull kind-init-${{ matrix.ip-family }}
15081510
15091511
- name: Install Kube-OVN
15101512
id: install
@@ -1658,13 +1660,16 @@ jobs:
16581660
docker load --input kube-ovn.tar
16591661
docker load --input vpc-nat-gateway.tar
16601662
1661-
- name: Create kind cluster and install CNIs
1662-
id: install
1663+
- name: Create kind cluster
16631664
env:
16641665
GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16651666
run: |
16661667
pipx install jinjanator
1667-
make kind-ghcr-pull kind-install-multus-cilium-kubeovn-non-primary-${{ matrix.ip-family }}
1668+
make kind-ghcr-pull kind-init-${{ matrix.ip-family }}
1669+
1670+
- name: Install Mults-CNI, Cilium, and Kube-OVN
1671+
id: install
1672+
run: make kind-install-multus-cilium-kubeovn-non-primary-${{ matrix.ip-family }}
16681673

16691674
- name: Run non-primary CNI e2e
16701675
id: e2e
@@ -1674,7 +1679,9 @@ jobs:
16741679
E2E_IP_FAMILY: ${{ matrix.ip-family }}
16751680
E2E_NETWORK_MODE: overlay
16761681
KUBE_OVN_PRIMARY_CNI: "false"
1677-
run: make kube-ovn-non-primary-cni-e2e
1682+
run: |
1683+
make kind-load-image-vpc-nat-gateway
1684+
make kube-ovn-non-primary-cni-e2e
16781685
16791686
- name: Collect k8s events
16801687
if: failure() && steps.e2e.conclusion == 'failure'

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ require (
4545
github.com/spf13/pflag v1.0.10
4646
github.com/stretchr/testify v1.11.1
4747
github.com/vishvananda/netlink v1.3.1
48+
go.podman.io/image/v5 v5.38.0
4849
go.uber.org/mock v0.6.0
4950
go.uber.org/zap v1.27.1
5051
go.universe.tf/metallb v0.15.3
@@ -238,6 +239,7 @@ require (
238239
go.opentelemetry.io/otel/sdk v1.39.0 // indirect
239240
go.opentelemetry.io/otel/trace v1.39.0 // indirect
240241
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
242+
go.podman.io/storage v1.61.0 // indirect
241243
go.uber.org/multierr v1.11.0 // indirect
242244
go.yaml.in/yaml/v2 v2.4.3 // indirect
243245
go.yaml.in/yaml/v3 v3.0.4 // indirect

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,10 @@ go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6
695695
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
696696
go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A=
697697
go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4=
698+
go.podman.io/image/v5 v5.38.0 h1:aUKrCANkPvze1bnhLJsaubcfz0d9v/bSDLnwsXJm6G4=
699+
go.podman.io/image/v5 v5.38.0/go.mod h1:hSIoIUzgBnmc4DjoIdzk63aloqVbD7QXDMkSE/cvG90=
700+
go.podman.io/storage v1.61.0 h1:5hD/oyRYt1f1gxgvect+8syZBQhGhV28dCw2+CZpx0Q=
701+
go.podman.io/storage v1.61.0/go.mod h1:A3UBK0XypjNZ6pghRhuxg62+2NIm5lcUGv/7XyMhMUI=
698702
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
699703
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
700704
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=

makefiles/kind.mk

Lines changed: 60 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ UNTAINT_CONTROL_PLANE ?= true
55
VPC_NAT_GW_IMG = $(REGISTRY)/vpc-nat-gateway:$(VERSION)
66

77
# Cilium configuration variables (fallback if not defined in main Makefile)
8-
CILIUM_VERSION ?= v1.18.4
8+
CILIUM_VERSION ?= v1.18.5
99
CILIUM_IMAGE_REPO ?= quay.io/cilium
1010

1111
# renovate: datasource=docker depName=kindest/node packageName=kindest/node versioning=semver
@@ -80,6 +80,17 @@ define kind_subctl_join
8080
$(call kubectl_wait_submariner_ready)
8181
endef
8282

83+
define kubectl_get_control_plane_ip
84+
$(shell \
85+
options=""; \
86+
if [ -n "$(1)" ]; then \
87+
options="--context kind-$(1)"; \
88+
fi; \
89+
kubectl $${options} get nodes -l node-role.kubernetes.io/control-plane \
90+
-o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}' \
91+
)
92+
endef
93+
8394
.PHONY: kind-network-create-underlay
8495
kind-network-create-underlay:
8596
$(eval UNDERLAY_NETWORK_ID = $(shell docker network ls -f name='^kind-underlay$$' --format '{{.ID}}'))
@@ -150,6 +161,13 @@ kind-init-ovn-ic-%: kind-clean-ovn-ic
150161
@n_worker=3 ip_family=$* auditing=$(KIND_AUDITING) $(MAKE) kind-generate-config
151162
$(call kind_create_cluster,yamls/kind.yaml,kube-ovn1,1)
152163

164+
.PHONY: kind-init-without-kube-proxy
165+
kind-init-without-kube-proxy: kind-init-without-kube-proxy-ipv4
166+
167+
.PHONY: kind-init-without-kube-proxy-%
168+
kind-init-without-kube-proxy-%: kind-clean
169+
@kube_proxy_mode=none $(MAKE) kind-init-$*
170+
153171
.PHONY: kind-init-cilium-chaining
154172
kind-init-cilium-chaining: kind-init-cilium-chaining-ipv4
155173

@@ -219,6 +237,10 @@ kind-init-bgp-ha: kind-clean-bgp kind-init
219237
kind-load-image:
220238
$(call kind_load_image,kube-ovn,$(REGISTRY)/kube-ovn:$(VERSION))
221239

240+
.PHONY: kind-load-image-vpc-nat-gateway
241+
kind-load-image-vpc-nat-gateway:
242+
$(call kind_load_image,kube-ovn,$(VPC_NAT_GW_IMG))
243+
222244
.PHONY: kind-install-chart
223245
kind-install-chart: kind-load-image untaint-control-plane install-chart
224246

@@ -471,25 +493,6 @@ kind-install-multus:
471493
kubectl -n kube-system set resources ds/kube-multus-ds -c kube-multus --limits=cpu=200m,memory=200Mi
472494
kubectl -n kube-system rollout status ds kube-multus-ds
473495

474-
.PHONY: kind-install-multus-primary
475-
kind-install-multus-primary:
476-
@echo "Installing Multus as primary CNI..."
477-
kubectl apply -f https://raw.githubusercontent.com/k8snetworkplumbingwg/multus-cni/master/deployments/multus-daemonset.yml
478-
@echo "Waiting for Multus daemonset to be ready..."
479-
kubectl rollout status daemonset/kube-multus-ds -n kube-system --timeout=300s
480-
481-
.PHONY: kind-update-multus-cilium-config
482-
kind-update-multus-cilium-config:
483-
@echo "Creating Cilium CNI configuration and updating Multus conflist..."
484-
@for node in $$(kubectl get nodes --no-headers -o custom-columns=":metadata.name"); do \
485-
echo "Creating Cilium CNI config on node: $$node"; \
486-
docker exec $$node sh -c 'mkdir -p /host/etc/cni/multus/net.d'; \
487-
docker exec $$node sh -c 'printf "{\n \"cniVersion\": \"0.3.1\",\n \"name\": \"cilium\",\n \"plugins\": [\n {\n \"type\": \"cilium-cni\",\n \"enable-debug\": false,\n \"log-file\": \"/var/run/cilium/cilium-cni.log\"\n }\n ]\n}" > /host/etc/cni/multus/net.d/05-cilium.conflist'; \
488-
echo "Updating Multus CNI configuration on node: $$node"; \
489-
docker exec $$node sh -c 'printf "{\n \"cniVersion\": \"0.3.1\",\n \"name\": \"multus-cni-network\",\n \"type\": \"multus\",\n \"cniConf\": \"/host/etc/cni/multus/net.d\",\n \"kubeconfig\": \"/etc/cni/net.d/multus.d/multus.kubeconfig\",\n \"delegates\": [\n {\n \"cniVersion\": \"0.3.1\",\n \"name\": \"cilium\",\n \"plugins\": [\n {\n \"enable-debug\": false,\n \"log-file\": \"/var/run/cilium/cilium-cni.log\",\n \"type\": \"cilium-cni\"\n }\n ]\n }\n ]\n}" > /etc/cni/net.d/00-multus.conf'; \
490-
done
491-
@echo "Cilium CNI configuration and Multus conflist created on all nodes"
492-
493496
.PHONY: kind-install-metallb
494497
kind-install-metallb:
495498
$(call docker_network_info,kind,kube-ovn-control-plane)
@@ -519,7 +522,7 @@ kind-install-metallb-pool-from-underlay: kind-load-image
519522

520523
.PHONY: kind-install-vpc-nat-gw
521524
kind-install-vpc-nat-gw:
522-
$(call kind_load_image,kube-ovn,$(VPC_NAT_GW_IMG))
525+
@$(MAKE) kind-load-image-vpc-nat-gateway
523526
@$(MAKE) ENABLE_NAT_GW=true CNI_CONFIG_PRIORITY=10 kind-install
524527
@$(MAKE) kind-install-multus
525528

@@ -547,7 +550,7 @@ kind-install-kubevirt:
547550

548551
.PHONY: kind-install-lb-svc
549552
kind-install-lb-svc:
550-
$(call kind_load_image,kube-ovn,$(VPC_NAT_GW_IMG))
553+
@$(MAKE) kind-load-image-vpc-nat-gateway
551554
@$(MAKE) ENABLE_LB_SVC=true CNI_CONFIG_PRIORITY=10 kind-install
552555
@$(MAKE) kind-install-multus
553556

@@ -570,7 +573,10 @@ kind-install-cilium-chaining: kind-install-cilium-chaining-ipv4
570573

571574
.PHONY: kind-install-cilium-chaining-%
572575
kind-install-cilium-chaining-%:
573-
$(eval KUBERNETES_SERVICE_HOST = $(shell kubectl get nodes kube-ovn-control-plane -o jsonpath='{.status.addresses[0].address}'))
576+
$(eval IPV4_ENABLED = $(shell if echo $* | grep -q ipv6; then echo false; else echo true; fi))
577+
$(eval IPV6_ENABLED = $(shell if echo $* | grep -q ipv4; then echo false; else echo true; fi))
578+
@echo "Installing Cilium with IPv4=$(IPV4_ENABLED) and IPv6=$(IPV6_ENABLED) ..."
579+
$(eval KUBERNETES_SERVICE_HOST = $(call kubectl_get_control_plane_ip))
574580
$(call kind_load_image,kube-ovn,$(CILIUM_IMAGE_REPO)/cilium:$(CILIUM_VERSION),1)
575581
$(call kind_load_image,kube-ovn,$(CILIUM_IMAGE_REPO)/operator-generic:$(CILIUM_VERSION),1)
576582
kubectl apply -f yamls/cilium-chaining.yaml
@@ -595,8 +601,8 @@ kind-install-cilium-chaining-%:
595601
--set hubble.enabled=true \
596602
--set envoy.enabled=false \
597603
--set sctp.enabled=true \
598-
--set ipv4.enabled=$(shell if echo $* | grep -q ipv6; then echo false; else echo true; fi) \
599-
--set ipv6.enabled=$(shell if echo $* | grep -q ipv4; then echo false; else echo true; fi) \
604+
--set ipv4.enabled=$(IPV4_ENABLED) \
605+
--set ipv6.enabled=$(IPV6_ENABLED) \
600606
--set routingMode=native \
601607
--set devices="eth+ ovn0 genev_sys_6081 vxlan_sys_4789" \
602608
--set forceDeviceDetection=true \
@@ -619,23 +625,25 @@ kind-install-cilium-delegate: kind-install-cilium-delegate-ipv4
619625

620626
.PHONY: kind-install-cilium-delegate-%
621627
kind-install-cilium-delegate-%:
622-
@echo "Installing Cilium as delegate CNI through Multus using Helm..."
623-
$(eval KUBERNETES_SERVICE_HOST = $(shell kubectl get nodes kube-ovn-control-plane -o jsonpath='{.status.addresses[0].address}'))
628+
$(eval IPV4_ENABLED = $(shell if echo $* | grep -q ipv6; then echo false; else echo true; fi))
629+
$(eval IPV6_ENABLED = $(shell if echo $* | grep -q ipv4; then echo false; else echo true; fi))
630+
@echo "Installing Cilium with IPv4=$(IPV4_ENABLED) and IPv6=$(IPV6_ENABLED) ..."
624631
$(call kind_load_image,kube-ovn,$(CILIUM_IMAGE_REPO)/cilium:$(CILIUM_VERSION),1)
625632
$(call kind_load_image,kube-ovn,$(CILIUM_IMAGE_REPO)/operator-generic:$(CILIUM_VERSION),1)
626633
helm repo add cilium https://helm.cilium.io/
627634
helm repo update cilium
628635
@echo "Installing Cilium via Helm with delegate configuration..."
629-
helm install cilium cilium/cilium \
636+
helm install cilium cilium/cilium --wait \
630637
--namespace kube-system \
631638
--version $(CILIUM_VERSION:v%=%) \
639+
--set image.useDigest=false \
640+
--set operator.image.useDigest=false \
632641
--set cni.exclusive=false \
633-
--set envoy.enabled=false
642+
--set envoy.enabled=false \
643+
--set ipv4.enabled=$(IPV4_ENABLED) \
644+
--set ipv6.enabled=$(IPV6_ENABLED)
634645
@echo "Waiting for Cilium to be ready..."
635-
kubectl wait --namespace kube-system --for=condition=ready pod -l k8s-app=cilium --timeout=300s
636-
@echo "Redeploying Multus..."
637-
kubectl -n kube-system set resources ds/kube-multus-ds -c kube-multus --limits=cpu=200m,memory=200Mi
638-
kubectl -n kube-system rollout status ds kube-multus-ds
646+
kubectl -n kube-system rollout status ds cilium --timeout 120s
639647

640648
.PHONY: kind-install-bgp
641649
kind-install-bgp: kind-install
@@ -805,7 +813,7 @@ kind-clean-bgp-ha:
805813

806814
.PHONY: kind-ghcr-pull
807815
kind-ghcr-pull:
808-
echo $${GHCR_TOKEN} | docker login ghcr.io -u github-actions --password-stdin
816+
@echo $${GHCR_TOKEN} | docker login ghcr.io -u github-actions --password-stdin
809817
docker pull ghcr.io/kubeovn/kindest-node:$(K8S_VERSION)
810818
docker tag ghcr.io/kubeovn/kindest-node:$(K8S_VERSION) kindest/node:$(K8S_VERSION)
811819

@@ -814,23 +822,19 @@ kind-install-multus-cilium-kubeovn-non-primary: kind-install-multus-cilium-kubeo
814822

815823
.PHONY: kind-install-multus-cilium-kubeovn-non-primary-%
816824
kind-install-multus-cilium-kubeovn-non-primary-%:
817-
@echo "Setting up KIND cluster with Multus primary CNI, Cilium delegate, and Kube-OVN secondary CNI..."
818-
@echo "1. Creating KIND cluster and initializing with no CNI..."
819-
$(MAKE) kind-init-$*
820-
@echo "2. Create underlay network and connect nodes..."
825+
@echo "Setting up KIND cluster with Multus-CNI, Cilium delegate as primary CNI, and Kube-OVN as secondary CNI..."
826+
@echo "1. Create underlay network and connect nodes..."
821827
@$(MAKE) kind-network-create-underlay
822828
@$(MAKE) kind-network-connect-underlay
823-
@echo "3. Installing Multus as Cilium configuration..."
824-
@$(MAKE) kind-update-multus-cilium-config
825-
@echo "4. Installing Multus as primary CNI..."
826-
@$(MAKE) kind-install-multus-primary
827-
@echo "5. Installing Cilium as delegate through Multus..."
829+
@echo "2. Installing Cilium as primary CNI..."
828830
@$(MAKE) kind-install-cilium-delegate-$*
829-
@echo "6. Installing Kube-OVN as secondary/non-primary CNI..."
830-
@$(MAKE) ENABLE_NON_PRIMARY_CNI=true CNI_CONFIG_PRIORITY=10 kind-install-chart
831+
@echo "3. Installing Multus-CNI..."
832+
@$(MAKE) kind-install-multus
833+
@echo "4. Installing Kube-OVN as secondary/non-primary CNI..."
834+
@$(MAKE) NET_STACK=$* ENABLE_NON_PRIMARY_CNI=true CNI_CONFIG_PRIORITY=10 kind-install-chart
831835
@echo "KIND cluster setup complete!"
832-
@echo " - Multus: Primary CNI for multi-CNI support"
833-
@echo " - Cilium: Delegate CNI for primary networking"
836+
@echo " - Multus: Multi-CNI support"
837+
@echo " - Cilium: Primary CNI"
834838
@echo " - Kube-OVN: Secondary CNI for additional network interfaces"
835839
@echo ""
836840
@echo "You can now run non-primary CNI tests with:"
@@ -842,20 +846,16 @@ kind-install-multus-cilium-kubeovn-non-primary-v2: kind-install-multus-cilium-ku
842846

843847
.PHONY: kind-install-multus-cilium-kubeovn-non-primary-v2-%
844848
kind-install-multus-cilium-kubeovn-non-primary-v2-%:
845-
@echo "Setting up KIND cluster with Multus primary CNI, Cilium delegate, and Kube-OVN secondary CNI..."
846-
@echo "1. Creating KIND cluster and initializing with no CNI..."
847-
@kube_proxy_mode=none $(MAKE) kind-init-$*
848-
@echo "2. Installing Multus as Cilium configuration..."
849-
@$(MAKE) kind-update-multus-cilium-config
850-
@echo "3. Installing Multus as primary CNI..."
851-
@$(MAKE) kind-install-multus-primary
852-
@echo "4. Installing Cilium as delegate through Multus..."
849+
@echo "Setting up KIND cluster with Multus-CNI, Cilium delegate as primary CNI, and Kube-OVN as secondary CNI..."
850+
@echo "1. Installing Cilium as primary CNI..."
853851
@$(MAKE) kind-install-cilium-delegate-$*
854-
@echo "5. Installing Kube-OVN as secondary/non-primary CNI..."
855-
@$(MAKE) ENABLE_NON_PRIMARY_CNI=true CNI_CONFIG_PRIORITY=10 kind-install-chart
852+
@echo "2. Installing Multus-CNI..."
853+
@$(MAKE) kind-install-multus
854+
@echo "3. Installing Kube-OVN as secondary/non-primary CNI..."
855+
@$(MAKE) NET_STACK=$* ENABLE_NON_PRIMARY_CNI=true CNI_CONFIG_PRIORITY=10 kind-install-chart
856856
@echo "KIND cluster setup complete!"
857-
@echo " - Multus: Primary CNI for multi-CNI support"
858-
@echo " - Cilium: Delegate CNI for primary networking"
857+
@echo " - Multus: Multi-CNI support"
858+
@echo " - Cilium: Primary CNI"
859859
@echo " - Kube-OVN: Secondary CNI for additional network interfaces"
860860
@echo ""
861861
@echo "You can now run non-primary CNI tests with:"
@@ -866,4 +866,4 @@ kind-install-multus-cilium-kubeovn-non-primary-v2-%:
866866
kind-setup-non-primary-cni: kind-install-multus-cilium-kubeovn-non-primary
867867

868868
.PHONY: kind-setup-non-primary-cni-v2
869-
kind-setup-non-primary-cni-v2: kind-install-multus-cilium-kubeovn-non-primary-v2
869+
kind-setup-non-primary-cni-v2: kind-install-multus-cilium-kubeovn-non-primary-v2

test/e2e/framework/framework.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import (
44
"context"
55
"fmt"
66
"os"
7+
"path"
78
"strings"
89
"time"
910

1011
nad "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/client/clientset/versioned"
1112
"github.com/onsi/ginkgo/v2"
13+
"go.podman.io/image/v5/docker/reference"
1214
extClientSet "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
1315
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1416
versionutil "k8s.io/apimachinery/pkg/util/version"
@@ -71,7 +73,11 @@ type Framework struct {
7173
ClusterIPFamily string
7274
// overlay/underlay/underlay-hairpin
7375
ClusterNetworkMode string
76+
// image info
7477
KubeOVNImage string
78+
KubeOVNImageDomain string
79+
KubeOVNImageRepo string
80+
KubeOVNImageTag string
7581
}
7682

7783
func (f *Framework) parseEnv() {
@@ -259,6 +265,15 @@ func (f *Framework) BeforeEach() {
259265
framework.Logf("Getting Kube-OVN image")
260266
f.KubeOVNImage = GetKubeOvnImage(f.ClientSet)
261267
framework.Logf("Got Kube-OVN image: %s", f.KubeOVNImage)
268+
ref, err := reference.Parse(f.KubeOVNImage)
269+
ExpectNoError(err)
270+
taggedRef := ref.(reference.Tagged)
271+
ExpectNotNil(taggedRef, "Failed to get tagged reference from Kube-OVN image")
272+
f.KubeOVNImageTag = taggedRef.Tag()
273+
namedRef := ref.(reference.Named)
274+
ExpectNotNil(namedRef, "Failed to get named reference from Kube-OVN image")
275+
f.KubeOVNImageDomain = reference.Domain(namedRef)
276+
f.KubeOVNImageRepo = reference.Path(namedRef)
262277
}
263278

264279
framework.TestContext.Host = ""
@@ -278,6 +293,19 @@ func (f *Framework) SkipVersionPriorTo(major, minor uint, reason string) {
278293
}
279294
}
280295

296+
// Image returns the image reference with the specified name.
297+
// .e.g. Image("vpc-nat-gateway") returns "docker.io/kubeovn/vpc-nat-gateway:v1.16.0"
298+
func (f *Framework) Image(name string) string {
299+
repo := path.Clean(path.Join(path.Dir(f.KubeOVNImageRepo), name))
300+
return fmt.Sprintf("%s/%s:%s", f.KubeOVNImageDomain, repo, f.KubeOVNImageTag)
301+
}
302+
303+
// VpcNatGatewayImage returns the VPC NAT gateway image reference.
304+
// .e.g. "docker.io/kubeovn/vpc-nat-gateway:v1.16.0"
305+
func (f *Framework) VpcNatGatewayImage() string {
306+
return f.Image("vpc-nat-gateway")
307+
}
308+
281309
func (f *Framework) ValidateFinalizers(obj metav1.Object) {
282310
ginkgo.GinkgoHelper()
283311

0 commit comments

Comments
 (0)