Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
30d73d6
make sure x ip crd exist and then update subnet status v4|6 using range
zbb88888 Dec 8, 2025
24454dd
fix: make sue all kinds of ip
zbb88888 Dec 8, 2025
06dcf7d
Enhance e2e tests for OVN VPC NAT Gateway and VIP
zbb88888 Dec 12, 2025
59f9484
fix iptable eip qos e2e
zbb88888 Dec 12, 2025
bcbd1d0
重命名并更新iptables VPC NAT网关的E2E测试目标
zbb88888 Dec 12, 2025
a3e5913
新增支持无默认EIP的VPC NAT网关创建功能,并更新测试用例
zbb88888 Dec 12, 2025
8573a56
新增支持无默认EIP的VPC NAT网关创建功能
zbb88888 Dec 12, 2025
c3ec365
优化E2E测试,统一随机后缀生成方式并增加等待逻辑以确保OVN EIP的最终化和子网状态更新
zbb88888 Dec 13, 2025
1370938
fix ovn vpc e2e
zbb88888 Dec 13, 2025
ce7a4dc
fix old finalizer
zbb88888 Dec 13, 2025
684d9b8
fix ovn vpc e2e
zbb88888 Dec 14, 2025
884ea0f
fix ovn vpc nat e2e
zbb88888 Dec 14, 2025
3ee1d70
fix lint
zbb88888 Dec 14, 2025
b7a6ca2
add test
zbb88888 Dec 14, 2025
efb6738
simple default external subnet
zbb88888 Dec 14, 2025
c308438
make sure create it self
zbb88888 Dec 14, 2025
0450134
rollback
zbb88888 Dec 14, 2025
184c487
debug provider network deleting process
zbb88888 Dec 14, 2025
e5093a1
串行执行
zbb88888 Dec 14, 2025
523b38e
串行执行
zbb88888 Dec 14, 2025
68874bb
fix webhook outdated update subnet
zbb88888 Dec 15, 2025
b3fa18a
make sure ovs br exist and then add its nic
zbb88888 Dec 15, 2025
b8d5d60
fix as self review
zbb88888 Dec 15, 2025
9bd3060
优化IP和EIP处理逻辑,移除冗余的finalizer添加步骤,确保在所有操作完成后更新子网状态
zbb88888 Dec 15, 2025
5c5a311
在创建或更新CR后,添加延迟以触发子网状态更新
zbb88888 Dec 15, 2025
baa100f
优化子网状态更新延迟,确保API服务器完成finalizer移除
zbb88888 Dec 15, 2025
c2bacde
fix webhook
zbb88888 Dec 16, 2025
5651048
优化OVN客户端创建逻辑,添加重试机制以提高连接成功率
zbb88888 Dec 16, 2025
e90f7c1
fix err
zbb88888 Dec 16, 2025
7973f46
make sure all del queue refer to a new deepcopy object, the origin pt…
zbb88888 Dec 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions makefiles/e2e.mk
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ e2e-build:
ginkgo build $(E2E_BUILD_FLAGS) ./test/e2e/multus
ginkgo build $(E2E_BUILD_FLAGS) ./test/e2e/non-primary-cni
ginkgo build $(E2E_BUILD_FLAGS) ./test/e2e/lb-svc
ginkgo build $(E2E_BUILD_FLAGS) ./test/e2e/ip
ginkgo build $(E2E_BUILD_FLAGS) ./test/e2e/vip
ginkgo build $(E2E_BUILD_FLAGS) ./test/e2e/vpc-egress-gateway
ginkgo build $(E2E_BUILD_FLAGS) ./test/e2e/iptables-vpc-nat-gw
Expand Down Expand Up @@ -188,6 +189,15 @@ kube-ovn-lb-svc-conformance-e2e:
ginkgo $(GINKGO_OUTPUT_OPT) $(GINKGO_PARALLEL_OPT) --randomize-all -v \
--focus=CNI:Kube-OVN ./test/e2e/lb-svc/lb-svc.test -- $(TEST_BIN_ARGS)

.PHONY: ip-conformance-e2e
ip-conformance-e2e:
ginkgo build $(E2E_BUILD_FLAGS) ./test/e2e/ip
E2E_BRANCH=$(E2E_BRANCH) \
E2E_IP_FAMILY=$(E2E_IP_FAMILY) \
E2E_NETWORK_MODE=$(E2E_NETWORK_MODE) \
ginkgo $(GINKGO_OUTPUT_OPT) $(GINKGO_PARALLEL_OPT) --randomize-all -v \
--focus=CNI:Kube-OVN ./test/e2e/ip/ip.test -- $(TEST_BIN_ARGS)

.PHONY: vip-conformance-e2e
vip-conformance-e2e:
ginkgo build $(E2E_BUILD_FLAGS) ./test/e2e/vip
Expand All @@ -205,15 +215,31 @@ vpc-egress-gateway-e2e:
ginkgo $(GINKGO_OUTPUT_OPT) $(GINKGO_PARALLEL_OPT) --randomize-all -v --timeout=30m \
--focus=CNI:Kube-OVN ./test/e2e/vpc-egress-gateway/vpc-egress-gateway.test -- $(TEST_BIN_ARGS)

.PHONY: iptables-vpc-nat-gw-conformance-e2e
iptables-vpc-nat-gw-conformance-e2e:
.PHONY: iptables-eip-conformance-e2e
iptables-eip-conformance-e2e:
ginkgo build $(E2E_BUILD_FLAGS) ./test/e2e/iptables-vpc-nat-gw
E2E_BRANCH=$(E2E_BRANCH) \
E2E_IP_FAMILY=$(E2E_IP_FAMILY) \
E2E_NETWORK_MODE=$(E2E_NETWORK_MODE) \
ginkgo $(GINKGO_OUTPUT_OPT) $(GINKGO_PARALLEL_OPT) --randomize-all -v \
--focus=CNI:Kube-OVN ./test/e2e/iptables-vpc-nat-gw/iptables-vpc-nat-gw.test -- $(TEST_BIN_ARGS)

.PHONY: iptables-eip-qos-conformance-e2e
iptables-eip-qos-conformance-e2e:
ginkgo build $(E2E_BUILD_FLAGS) ./test/e2e/iptables-eip-qos
E2E_BRANCH=$(E2E_BRANCH) \
E2E_IP_FAMILY=$(E2E_IP_FAMILY) \
E2E_NETWORK_MODE=$(E2E_NETWORK_MODE) \
ginkgo $(GINKGO_OUTPUT_OPT) --randomize-all -v \
--focus=CNI:Kube-OVN ./test/e2e/iptables-eip-qos/iptables-eip-qos.test -- $(TEST_BIN_ARGS)

.PHONY: iptables-vpc-nat-gw-conformance-e2e
iptables-vpc-nat-gw-conformance-e2e:
$(MAKE) iptables-eip-conformance-e2e
$(MAKE) iptables-eip-qos-conformance-e2e



.PHONY: ovn-vpc-nat-gw-conformance-e2e
ovn-vpc-nat-gw-conformance-e2e:
ginkgo build $(E2E_BUILD_FLAGS) ./test/e2e/ovn-vpc-nat-gw
Expand Down
2 changes: 2 additions & 0 deletions makefiles/ut.mk
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
ut:
ginkgo -mod=mod --show-node-events --poll-progress-after=60s $(GINKGO_OUTPUT_OPT) -v test/unittest
go test -coverprofile=profile.cov $$(go list ./pkg/... | grep -vw '^github.com/kubeovn/kube-ovn/pkg/client')
@echo "Running e2e framework unit tests..."
go test -v ./test/e2e/framework/docker

.PHONY: ovs-sandbox
ovs-sandbox: clean-ovs-sandbox
Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/admin_network_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func (c *Controller) enqueueDeleteAnp(obj any) {
}

klog.V(3).Infof("enqueue delete anp %s", cache.MetaObjectToName(anp).String())
c.deleteAnpQueue.Add(anp)
c.deleteAnpQueue.Add(anp.DeepCopy())
}

func (c *Controller) enqueueUpdateAnp(oldObj, newObj any) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/baseline_admin_network_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (c *Controller) enqueueDeleteBanp(obj any) {
}

klog.V(3).Infof("enqueue delete bnp %s", cache.MetaObjectToName(bnp).String())
c.deleteBanpQueue.Add(bnp)
c.deleteBanpQueue.Add(bnp.DeepCopy())
}

func (c *Controller) enqueueUpdateBanp(oldObj, newObj any) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/cluster_network_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func (c *Controller) enqueueDeleteCnp(obj any) {
}

klog.V(3).Infof("enqueue delete cnp %s", cache.MetaObjectToName(cnp).String())
c.deleteCnpQueue.Add(cnp)
c.deleteCnpQueue.Add(cnp.DeepCopy())
}

func (c *Controller) handleAddCnp(key string) (err error) {
Expand Down
8 changes: 4 additions & 4 deletions pkg/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ type Controller struct {
addIptablesEipQueue workqueue.TypedRateLimitingInterface[string]
updateIptablesEipQueue workqueue.TypedRateLimitingInterface[string]
resetIptablesEipQueue workqueue.TypedRateLimitingInterface[string]
delIptablesEipQueue workqueue.TypedRateLimitingInterface[string]
delIptablesEipQueue workqueue.TypedRateLimitingInterface[*kubeovnv1.IptablesEIP]

iptablesFipsLister kubeovnlister.IptablesFIPRuleLister
iptablesFipSynced cache.InformerSynced
Expand All @@ -184,7 +184,7 @@ type Controller struct {
addOvnEipQueue workqueue.TypedRateLimitingInterface[string]
updateOvnEipQueue workqueue.TypedRateLimitingInterface[string]
resetOvnEipQueue workqueue.TypedRateLimitingInterface[string]
delOvnEipQueue workqueue.TypedRateLimitingInterface[string]
delOvnEipQueue workqueue.TypedRateLimitingInterface[*kubeovnv1.OvnEip]

ovnFipsLister kubeovnlister.OvnFipLister
ovnFipSynced cache.InformerSynced
Expand Down Expand Up @@ -472,7 +472,7 @@ func Run(ctx context.Context, config *Configuration) {
addIptablesEipQueue: newTypedRateLimitingQueue("AddIptablesEip", custCrdRateLimiter),
updateIptablesEipQueue: newTypedRateLimitingQueue("UpdateIptablesEip", custCrdRateLimiter),
resetIptablesEipQueue: newTypedRateLimitingQueue("ResetIptablesEip", custCrdRateLimiter),
delIptablesEipQueue: newTypedRateLimitingQueue("DeleteIptablesEip", custCrdRateLimiter),
delIptablesEipQueue: newTypedRateLimitingQueue[*kubeovnv1.IptablesEIP]("DeleteIptablesEip", nil),

iptablesFipsLister: iptablesFipInformer.Lister(),
iptablesFipSynced: iptablesFipInformer.Informer().HasSynced,
Expand Down Expand Up @@ -563,7 +563,7 @@ func Run(ctx context.Context, config *Configuration) {
addOvnEipQueue: newTypedRateLimitingQueue("AddOvnEip", custCrdRateLimiter),
updateOvnEipQueue: newTypedRateLimitingQueue("UpdateOvnEip", custCrdRateLimiter),
resetOvnEipQueue: newTypedRateLimitingQueue("ResetOvnEip", custCrdRateLimiter),
delOvnEipQueue: newTypedRateLimitingQueue("DeleteOvnEip", custCrdRateLimiter),
delOvnEipQueue: newTypedRateLimitingQueue[*kubeovnv1.OvnEip]("DeleteOvnEip", nil),

ovnFipsLister: ovnFipInformer.Lister(),
ovnFipSynced: ovnFipInformer.Informer().HasSynced,
Expand Down
2 changes: 2 additions & 0 deletions pkg/controller/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ func newFakeControllerWithOptions(t *testing.T, opts *FakeControllerOptions) (*f
serviceInformer := kubeInformerFactory.Core().V1().Services()
namespaceInformer := kubeInformerFactory.Core().V1().Namespaces()
podInformer := kubeInformerFactory.Core().V1().Pods()
configMapInformer := kubeInformerFactory.Core().V1().ConfigMaps()

nadInformerFactory := nadinformers.NewSharedInformerFactory(nadClient, 0)
nadInformer := nadInformerFactory.K8sCniCncfIo().V1().NetworkAttachmentDefinitions()
Expand Down Expand Up @@ -149,6 +150,7 @@ func newFakeControllerWithOptions(t *testing.T, opts *FakeControllerOptions) (*f
subnetSynced: alwaysReady,
netAttachLister: nadInformer.Lister(),
netAttachSynced: alwaysReady,
configMapsLister: configMapInformer.Lister(),
OVNNbClient: mockOvnClient,
syncVirtualPortsQueue: newTypedRateLimitingQueue[string]("SyncVirtualPort", nil),
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/dns_name_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func (c *Controller) enqueueDeleteDNSNameResolver(obj any) {
}

klog.V(3).Infof("enqueue delete dns name resolver %s", cache.MetaObjectToName(dnsNameResolver).String())
c.deleteDNSNameResolverQueue.Add(dnsNameResolver)
c.deleteDNSNameResolverQueue.Add(dnsNameResolver.DeepCopy())
}

func (c *Controller) handleAddOrUpdateDNSNameResolver(key string) error {
Expand Down
105 changes: 95 additions & 10 deletions pkg/controller/external_gw.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,16 @@ func (c *Controller) establishExternalGateway(config map[string]string) error {
klog.Errorf("failed to get gateway chassis, %v", err)
return err
}

// Get external gateway switch using centralized logic
externalGwSwitch, err := c.getExternalGatewaySwitchWithConfigMap(config)
if err != nil {
klog.Errorf("failed to get external gateway switch: %v", err)
return err
}

var lrpIP, lrpMac string
lrpName := fmt.Sprintf("%s-%s", c.config.ClusterRouter, c.config.ExternalGatewaySwitch)
lrpName := fmt.Sprintf("%s-%s", c.config.ClusterRouter, externalGwSwitch)
lrp, err := c.OVNNbClient.GetLogicalRouterPort(lrpName, true)
if err != nil {
klog.Errorf("failed to get lrp %s, %v", lrpName, err)
Expand All @@ -159,7 +167,7 @@ func (c *Controller) establishExternalGateway(config map[string]string) error {
lrpMac = lrp.MAC
lrpIP = lrp.Networks[0]
case config["nic-ip"] == "":
if lrpIP, lrpMac, err = c.createDefaultVpcLrpEip(); err != nil {
if lrpIP, lrpMac, err = c.createDefaultVpcLrpEip(externalGwSwitch); err != nil {
klog.Errorf("failed to create ovn eip for default vpc lrp: %v", err)
return err
}
Expand All @@ -168,22 +176,22 @@ func (c *Controller) establishExternalGateway(config map[string]string) error {
lrpMac = config["nic-mac"]
}

if err := c.OVNNbClient.CreateGatewayLogicalSwitch(c.config.ExternalGatewaySwitch, c.config.ClusterRouter, c.config.ExternalGatewayNet, lrpIP, lrpMac, c.config.ExternalGatewayVlanID, chassises...); err != nil {
klog.Errorf("failed to create external gateway switch %s: %v", c.config.ExternalGatewaySwitch, err)
if err := c.OVNNbClient.CreateGatewayLogicalSwitch(externalGwSwitch, c.config.ClusterRouter, c.config.ExternalGatewayNet, lrpIP, lrpMac, c.config.ExternalGatewayVlanID, chassises...); err != nil {
klog.Errorf("failed to create external gateway switch %s: %v", externalGwSwitch, err)
return err
}

return nil
}

func (c *Controller) createDefaultVpcLrpEip() (string, string, error) {
cachedSubnet, err := c.subnetsLister.Get(c.config.ExternalGatewaySwitch)
func (c *Controller) createDefaultVpcLrpEip(externalGwSwitch string) (string, string, error) {
cachedSubnet, err := c.subnetsLister.Get(externalGwSwitch)
if err != nil {
klog.Errorf("failed to get subnet %s, %v", c.config.ExternalGatewaySwitch, err)
klog.Errorf("failed to get subnet %s, %v", externalGwSwitch, err)
return "", "", err
}
needCreateEip := false
lrpEipName := fmt.Sprintf("%s-%s", c.config.ClusterRouter, c.config.ExternalGatewaySwitch)
lrpEipName := fmt.Sprintf("%s-%s", c.config.ClusterRouter, externalGwSwitch)
cachedEip, err := c.ovnEipsLister.Get(lrpEipName)
if err != nil {
if !k8serrors.IsNotFound(err) {
Expand All @@ -203,12 +211,12 @@ func (c *Controller) createDefaultVpcLrpEip() (string, string, error) {
}
} else {
var v6ip string
v4ip, v6ip, mac, err = c.acquireIPAddress(c.config.ExternalGatewaySwitch, lrpEipName, lrpEipName)
v4ip, v6ip, mac, err = c.acquireIPAddress(externalGwSwitch, lrpEipName, lrpEipName)
if err != nil {
klog.Errorf("failed to acquire ip address for default vpc lrp %s, %v", lrpEipName, err)
return "", "", err
}
if err := c.createOrUpdateOvnEipCR(lrpEipName, c.config.ExternalGatewaySwitch, v4ip, v6ip, mac, util.OvnEipTypeLRP); err != nil {
if err := c.createOrUpdateOvnEipCR(lrpEipName, externalGwSwitch, v4ip, v6ip, mac, util.OvnEipTypeLRP); err != nil {
klog.Errorf("failed to create ovn lrp eip %s, %v", lrpEipName, err)
return "", "", err
}
Expand All @@ -221,6 +229,83 @@ func (c *Controller) createDefaultVpcLrpEip() (string, string, error) {
return v4ipCidr, mac, nil
}

// getExternalGatewaySwitchWithConfigMap determines which external gateway switch to use.
// Two modes:
// - Traditional mode: c.config.ExternalGatewaySwitch (OVN LogicalSwitch, NOT managed by Subnet CRD)
// - ConfigMap mode: User-specified subnet in ConfigMap (managed by Subnet CRD)
// Logic:
// 1. ConfigMap not specified -> use default (traditional mode)
// 2. ConfigMap same as default -> use default (traditional mode)
// 3. ConfigMap different from default -> check conflict and verify ConfigMap subnet exists
func (c *Controller) getExternalGatewaySwitchWithConfigMap(configData map[string]string) (string, error) {
configMapSwitch := configData["external-gw-switch"]
defaultSwitch := c.config.ExternalGatewaySwitch

// 1. ConfigMap not specified -> use default
if configMapSwitch == "" {
return defaultSwitch, nil
}

// 2. ConfigMap specified same as default -> use default
if configMapSwitch == defaultSwitch {
return defaultSwitch, nil
}

// 3. ConfigMap specified different from default
// Check if default logical switch exists in OVN (configuration conflict)
// Note: c.config.ExternalGatewaySwitch is OVN LogicalSwitch, NOT Subnet CRD
exists, err := c.OVNNbClient.LogicalSwitchExists(defaultSwitch)
if err != nil {
klog.Errorf("failed to check if default logical switch %s exists: %v", defaultSwitch, err)
return "", err
}
if exists {
// Default logical switch exists - conflict
err := fmt.Errorf("configuration conflict: default external logical switch %s exists, but ConfigMap specifies different subnet %s. Please use only one mode: either remove the default logical switch or remove the ConfigMap setting", defaultSwitch, configMapSwitch)
klog.Error(err)
return "", err
}

// Default subnet does not exist, verify ConfigMap-specified subnet exists
_, err = c.subnetsLister.Get(configMapSwitch)
if err != nil {
if k8serrors.IsNotFound(err) {
err := fmt.Errorf("ConfigMap specifies external subnet %s, but it does not exist. Please create the subnet first or update the ConfigMap", configMapSwitch)
klog.Error(err)
return "", err
}
err := fmt.Errorf("failed to get subnet %s from lister: %w", configMapSwitch, err)
klog.Error(err)
return "", err
}

return configMapSwitch, nil
}

// getConfigDefaultExternalSwitch determines which (from config or configmap) external gateway switch to use
// ConfigMap not specified -> use default;
// default not exists + ConfigMap specified -> use ConfigMap
func (c *Controller) getConfigDefaultExternalSwitch() (string, error) {
cm, err := c.configMapsLister.ConfigMaps(c.config.ExternalGatewayConfigNS).Get(util.ExternalGatewayConfig)
if err != nil {
if k8serrors.IsNotFound(err) {
// ConfigMap doesn't exist, use default
return c.config.ExternalGatewaySwitch, nil
}
err = fmt.Errorf("failed to get ConfigMap %s: %w", util.ExternalGatewayConfig, err)
klog.Error(err)
return "", err
}

// Check if ConfigMap is enabled
if cm.Data["enable-external-gw"] == "false" {
return c.config.ExternalGatewaySwitch, nil
}

// Use the centralized logic
return c.getExternalGatewaySwitchWithConfigMap(cm.Data)
}

func (c *Controller) getGatewayChassis(config map[string]string) ([]string, error) {
chassises := []string{}
nodes, err := c.nodesLister.List(externalGatewayNodeSelector)
Expand Down
Loading
Loading