Skip to content

Commit 547ea5e

Browse files
authored
ci: fix non-primary cni e2e test (#6127)
Signed-off-by: zhangzujian <zhangzujian.7@gmail.com>
1 parent b6a25a2 commit 547ea5e

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

@@ -474,25 +496,6 @@ kind-install-multus:
474496
kubectl -n kube-system set resources ds/kube-multus-ds -c kube-multus --limits=cpu=200m,memory=200Mi
475497
kubectl -n kube-system rollout status ds kube-multus-ds
476498

477-
.PHONY: kind-install-multus-primary
478-
kind-install-multus-primary:
479-
@echo "Installing Multus as primary CNI..."
480-
kubectl apply -f https://raw.githubusercontent.com/k8snetworkplumbingwg/multus-cni/master/deployments/multus-daemonset.yml
481-
@echo "Waiting for Multus daemonset to be ready..."
482-
kubectl rollout status daemonset/kube-multus-ds -n kube-system --timeout=300s
483-
484-
.PHONY: kind-update-multus-cilium-config
485-
kind-update-multus-cilium-config:
486-
@echo "Creating Cilium CNI configuration and updating Multus conflist..."
487-
@for node in $$(kubectl get nodes --no-headers -o custom-columns=":metadata.name"); do \
488-
echo "Creating Cilium CNI config on node: $$node"; \
489-
docker exec $$node sh -c 'mkdir -p /host/etc/cni/multus/net.d'; \
490-
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'; \
491-
echo "Updating Multus CNI configuration on node: $$node"; \
492-
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'; \
493-
done
494-
@echo "Cilium CNI configuration and Multus conflist created on all nodes"
495-
496499
.PHONY: kind-install-metallb
497500
kind-install-metallb:
498501
$(call docker_network_info,kind,kube-ovn-control-plane)
@@ -522,7 +525,7 @@ kind-install-metallb-pool-from-underlay: kind-load-image
522525

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

@@ -550,7 +553,7 @@ kind-install-kubevirt:
550553

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

@@ -573,7 +576,10 @@ kind-install-cilium-chaining: kind-install-cilium-chaining-ipv4
573576

574577
.PHONY: kind-install-cilium-chaining-%
575578
kind-install-cilium-chaining-%:
576-
$(eval KUBERNETES_SERVICE_HOST = $(shell kubectl get nodes kube-ovn-control-plane -o jsonpath='{.status.addresses[0].address}'))
579+
$(eval IPV4_ENABLED = $(shell if echo $* | grep -q ipv6; then echo false; else echo true; fi))
580+
$(eval IPV6_ENABLED = $(shell if echo $* | grep -q ipv4; then echo false; else echo true; fi))
581+
@echo "Installing Cilium with IPv4=$(IPV4_ENABLED) and IPv6=$(IPV6_ENABLED) ..."
582+
$(eval KUBERNETES_SERVICE_HOST = $(call kubectl_get_control_plane_ip))
577583
$(call kind_load_image,kube-ovn,$(CILIUM_IMAGE_REPO)/cilium:$(CILIUM_VERSION),1)
578584
$(call kind_load_image,kube-ovn,$(CILIUM_IMAGE_REPO)/operator-generic:$(CILIUM_VERSION),1)
579585
kubectl apply -f yamls/cilium-chaining.yaml
@@ -598,8 +604,8 @@ kind-install-cilium-chaining-%:
598604
--set hubble.enabled=true \
599605
--set envoy.enabled=false \
600606
--set sctp.enabled=true \
601-
--set ipv4.enabled=$(shell if echo $* | grep -q ipv6; then echo false; else echo true; fi) \
602-
--set ipv6.enabled=$(shell if echo $* | grep -q ipv4; then echo false; else echo true; fi) \
607+
--set ipv4.enabled=$(IPV4_ENABLED) \
608+
--set ipv6.enabled=$(IPV6_ENABLED) \
603609
--set routingMode=native \
604610
--set devices="eth+ ovn0 genev_sys_6081 vxlan_sys_4789" \
605611
--set forceDeviceDetection=true \
@@ -622,23 +628,25 @@ kind-install-cilium-delegate: kind-install-cilium-delegate-ipv4
622628

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

643651
.PHONY: kind-install-bgp
644652
kind-install-bgp: kind-install
@@ -808,7 +816,7 @@ kind-clean-bgp-ha:
808816

809817
.PHONY: kind-ghcr-pull
810818
kind-ghcr-pull:
811-
echo $${GHCR_TOKEN} | docker login ghcr.io -u github-actions --password-stdin
819+
@echo $${GHCR_TOKEN} | docker login ghcr.io -u github-actions --password-stdin
812820
docker pull ghcr.io/kubeovn/kindest-node:$(K8S_VERSION)
813821
docker tag ghcr.io/kubeovn/kindest-node:$(K8S_VERSION) kindest/node:$(K8S_VERSION)
814822

@@ -817,23 +825,19 @@ kind-install-multus-cilium-kubeovn-non-primary: kind-install-multus-cilium-kubeo
817825

818826
.PHONY: kind-install-multus-cilium-kubeovn-non-primary-%
819827
kind-install-multus-cilium-kubeovn-non-primary-%:
820-
@echo "Setting up KIND cluster with Multus primary CNI, Cilium delegate, and Kube-OVN secondary CNI..."
821-
@echo "1. Creating KIND cluster and initializing with no CNI..."
822-
$(MAKE) kind-init-$*
823-
@echo "2. Create underlay network and connect nodes..."
828+
@echo "Setting up KIND cluster with Multus-CNI, Cilium delegate as primary CNI, and Kube-OVN as secondary CNI..."
829+
@echo "1. Create underlay network and connect nodes..."
824830
@$(MAKE) kind-network-create-underlay
825831
@$(MAKE) kind-network-connect-underlay
826-
@echo "3. Installing Multus as Cilium configuration..."
827-
@$(MAKE) kind-update-multus-cilium-config
828-
@echo "4. Installing Multus as primary CNI..."
829-
@$(MAKE) kind-install-multus-primary
830-
@echo "5. Installing Cilium as delegate through Multus..."
832+
@echo "2. Installing Cilium as primary CNI..."
831833
@$(MAKE) kind-install-cilium-delegate-$*
832-
@echo "6. Installing Kube-OVN as secondary/non-primary CNI..."
833-
@$(MAKE) ENABLE_NON_PRIMARY_CNI=true CNI_CONFIG_PRIORITY=10 kind-install-chart
834+
@echo "3. Installing Multus-CNI..."
835+
@$(MAKE) kind-install-multus
836+
@echo "4. Installing Kube-OVN as secondary/non-primary CNI..."
837+
@$(MAKE) NET_STACK=$* ENABLE_NON_PRIMARY_CNI=true CNI_CONFIG_PRIORITY=10 kind-install-chart
834838
@echo "KIND cluster setup complete!"
835-
@echo " - Multus: Primary CNI for multi-CNI support"
836-
@echo " - Cilium: Delegate CNI for primary networking"
839+
@echo " - Multus: Multi-CNI support"
840+
@echo " - Cilium: Primary CNI"
837841
@echo " - Kube-OVN: Secondary CNI for additional network interfaces"
838842
@echo ""
839843
@echo "You can now run non-primary CNI tests with:"
@@ -845,20 +849,16 @@ kind-install-multus-cilium-kubeovn-non-primary-v2: kind-install-multus-cilium-ku
845849

846850
.PHONY: kind-install-multus-cilium-kubeovn-non-primary-v2-%
847851
kind-install-multus-cilium-kubeovn-non-primary-v2-%:
848-
@echo "Setting up KIND cluster with Multus primary CNI, Cilium delegate, and Kube-OVN secondary CNI..."
849-
@echo "1. Creating KIND cluster and initializing with no CNI..."
850-
@kube_proxy_mode=none $(MAKE) kind-init-$*
851-
@echo "2. Installing Multus as Cilium configuration..."
852-
@$(MAKE) kind-update-multus-cilium-config
853-
@echo "3. Installing Multus as primary CNI..."
854-
@$(MAKE) kind-install-multus-primary
855-
@echo "4. Installing Cilium as delegate through Multus..."
852+
@echo "Setting up KIND cluster with Multus-CNI, Cilium delegate as primary CNI, and Kube-OVN as secondary CNI..."
853+
@echo "1. Installing Cilium as primary CNI..."
856854
@$(MAKE) kind-install-cilium-delegate-$*
857-
@echo "5. Installing Kube-OVN as secondary/non-primary CNI..."
858-
@$(MAKE) ENABLE_NON_PRIMARY_CNI=true CNI_CONFIG_PRIORITY=10 kind-install-chart
855+
@echo "2. Installing Multus-CNI..."
856+
@$(MAKE) kind-install-multus
857+
@echo "3. Installing Kube-OVN as secondary/non-primary CNI..."
858+
@$(MAKE) NET_STACK=$* ENABLE_NON_PRIMARY_CNI=true CNI_CONFIG_PRIORITY=10 kind-install-chart
859859
@echo "KIND cluster setup complete!"
860-
@echo " - Multus: Primary CNI for multi-CNI support"
861-
@echo " - Cilium: Delegate CNI for primary networking"
860+
@echo " - Multus: Multi-CNI support"
861+
@echo " - Cilium: Primary CNI"
862862
@echo " - Kube-OVN: Secondary CNI for additional network interfaces"
863863
@echo ""
864864
@echo "You can now run non-primary CNI tests with:"
@@ -869,4 +869,4 @@ kind-install-multus-cilium-kubeovn-non-primary-v2-%:
869869
kind-setup-non-primary-cni: kind-install-multus-cilium-kubeovn-non-primary
870870

871871
.PHONY: kind-setup-non-primary-cni-v2
872-
kind-setup-non-primary-cni-v2: kind-install-multus-cilium-kubeovn-non-primary-v2
872+
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)