• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kubeovn / kube-ovn / 25917889230

15 May 2026 12:27PM UTC coverage: 24.552% (-0.04%) from 24.591%
25917889230

push

github

oilbeater
fix(controller): make BgpConf/EvpnConf informers optional (#6726) (#6737)

* fix(controller): make BgpConf/EvpnConf informers optional (#6726)

The kube-ovn-controller used to unconditionally add the BgpConf and
EvpnConf informers to its WaitForCacheSync list. On clusters upgraded
from <v1.16 via Helm those CRDs are missing (Helm does not re-apply
the chart's crds/ directory on `helm upgrade`), so the controller
hangs forever in "Waiting for informer caches to sync" and breaks
IPAM cluster-wide.

Treat BgpConf/EvpnConf like the other optional CRDs (NetworkAttachment,
ServiceCIDR):

* Detect the CRDs at startup via the discovery API and only register
  the informers when present.
* When missing, start a 10s background poller that picks them up once
  they appear, with no controller restart required.
* Publish the lister/synced fields only after WaitForCacheSync returns
  true so concurrent VEG reconcilers cannot observe a non-nil lister
  backed by an empty cache.
* Guard the vpc-egress-gateway consumer paths with a nil-lister check
  that surfaces a clear error and lets the workqueue retry.

Add an e2e regression test (kube-ovn/optional_crd) that deletes both
CRDs, restarts the controller and asserts the rollout completes and
IPAM still works, then restores the CRDs and verifies the controller
self-heals.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Mengxin Liu <liumengxinfly@gmail.com>

* fix(controller): address review feedback on optional BgpConf/EvpnConf (#6726)

Two follow-ups requested by Copilot on PR #6737:

* Race-free publication of the optional listers. The
  bgpConfLister/evpnConfLister fields are now atomic.Pointer values so
  the background poller's Store happens-before the VEG worker's Load,
  eliminating the data race flagged in bgp_evpn_conf.go and
  vpc_egress_gateway.go.

* Fail-fast e2e polling. The three wait loops in the new optional_crd
  spec previously masked every error other than NotFo... (continued)

0 of 107 new or added lines in 3 files covered. (0.0%)

13842 of 56379 relevant lines covered (24.55%)

0.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

1.13
/pkg/controller/controller.go
1
package controller
2

3
import (
4
        "context"
5
        "fmt"
6
        "runtime"
7
        "strings"
8
        "sync"
9
        "sync/atomic"
10
        "time"
11

12
        netAttach "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/client/informers/externalversions"
13
        netAttachv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/client/listers/k8s.cni.cncf.io/v1"
14
        "github.com/puzpuzpuz/xsync/v4"
15
        "golang.org/x/time/rate"
16
        corev1 "k8s.io/api/core/v1"
17
        k8serrors "k8s.io/apimachinery/pkg/api/errors"
18
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
19
        "k8s.io/apimachinery/pkg/labels"
20
        utilruntime "k8s.io/apimachinery/pkg/util/runtime"
21
        "k8s.io/apimachinery/pkg/util/wait"
22
        "k8s.io/client-go/discovery"
23
        kubeinformers "k8s.io/client-go/informers"
24
        "k8s.io/client-go/kubernetes/scheme"
25
        typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
26
        appsv1 "k8s.io/client-go/listers/apps/v1"
27
        certListerv1 "k8s.io/client-go/listers/certificates/v1"
28
        v1 "k8s.io/client-go/listers/core/v1"
29
        discoveryv1 "k8s.io/client-go/listers/discovery/v1"
30
        netv1 "k8s.io/client-go/listers/networking/v1"
31
        "k8s.io/client-go/tools/cache"
32
        "k8s.io/client-go/tools/record"
33
        "k8s.io/client-go/util/workqueue"
34
        "k8s.io/klog/v2"
35
        "k8s.io/utils/keymutex"
36
        "k8s.io/utils/set"
37
        v1alpha1 "sigs.k8s.io/network-policy-api/apis/v1alpha1"
38
        netpolv1alpha2 "sigs.k8s.io/network-policy-api/apis/v1alpha2"
39
        anpinformer "sigs.k8s.io/network-policy-api/pkg/client/informers/externalversions"
40
        anplister "sigs.k8s.io/network-policy-api/pkg/client/listers/apis/v1alpha1"
41
        anplisterv1alpha2 "sigs.k8s.io/network-policy-api/pkg/client/listers/apis/v1alpha2"
42

43
        kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1"
44
        kubeovninformer "github.com/kubeovn/kube-ovn/pkg/client/informers/externalversions"
45
        kubeovnlister "github.com/kubeovn/kube-ovn/pkg/client/listers/kubeovn/v1"
46
        "github.com/kubeovn/kube-ovn/pkg/informer"
47
        ovnipam "github.com/kubeovn/kube-ovn/pkg/ipam"
48
        "github.com/kubeovn/kube-ovn/pkg/ovs"
49
        "github.com/kubeovn/kube-ovn/pkg/util"
50
)
51

52
const controllerAgentName = "kube-ovn-controller"
53

54
const (
55
        logicalSwitchKey              = "ls"
56
        logicalRouterKey              = "lr"
57
        portGroupKey                  = "pg"
58
        networkPolicyKey              = "np"
59
        sgKey                         = "sg"
60
        sgsKey                        = "security_groups"
61
        u2oKey                        = "u2o"
62
        adminNetworkPolicyKey         = "anp"
63
        baselineAdminNetworkPolicyKey = "banp"
64
        ippoolKey                     = "ippool"
65
        clusterNetworkPolicyKey       = "cnp"
66
)
67

68
// Controller is kube-ovn main controller that watch ns/pod/node/svc/ep and operate ovn
69
type Controller struct {
70
        config *Configuration
71

72
        ipam             *ovnipam.IPAM
73
        namedPort        *NamedPort
74
        anpPrioNameMap   map[int32]string
75
        anpNamePrioMap   map[string]int32
76
        bnpPrioNameMap   map[int32]string
77
        bnpNamePrioMap   map[string]int32
78
        priorityMapMutex sync.RWMutex
79

80
        OVNNbClient ovs.NbClient
81
        OVNSbClient ovs.SbClient
82

83
        // ExternalGatewayType define external gateway type, centralized
84
        ExternalGatewayType string
85

86
        podsLister             v1.PodLister
87
        podsSynced             cache.InformerSynced
88
        addOrUpdatePodQueue    workqueue.TypedRateLimitingInterface[string]
89
        deletePodQueue         workqueue.TypedRateLimitingInterface[string]
90
        deletingPodObjMap      *xsync.Map[string, *corev1.Pod]
91
        deletingNodeObjMap     *xsync.Map[string, *corev1.Node]
92
        updatePodSecurityQueue workqueue.TypedRateLimitingInterface[string]
93
        podKeyMutex            keymutex.KeyMutex
94

95
        vpcsLister           kubeovnlister.VpcLister
96
        vpcSynced            cache.InformerSynced
97
        addOrUpdateVpcQueue  workqueue.TypedRateLimitingInterface[string]
98
        vpcLastPoliciesMap   *xsync.Map[string, string]
99
        delVpcQueue          workqueue.TypedRateLimitingInterface[*kubeovnv1.Vpc]
100
        updateVpcStatusQueue workqueue.TypedRateLimitingInterface[string]
101
        vpcKeyMutex          keymutex.KeyMutex
102

103
        vpcNatGatewayLister           kubeovnlister.VpcNatGatewayLister
104
        vpcNatGatewaySynced           cache.InformerSynced
105
        addOrUpdateVpcNatGatewayQueue workqueue.TypedRateLimitingInterface[string]
106
        delVpcNatGatewayQueue         workqueue.TypedRateLimitingInterface[string]
107
        initVpcNatGatewayQueue        workqueue.TypedRateLimitingInterface[string]
108
        updateVpcEipQueue             workqueue.TypedRateLimitingInterface[string]
109
        updateVpcFloatingIPQueue      workqueue.TypedRateLimitingInterface[string]
110
        updateVpcDnatQueue            workqueue.TypedRateLimitingInterface[string]
111
        updateVpcSnatQueue            workqueue.TypedRateLimitingInterface[string]
112
        updateVpcSubnetQueue          workqueue.TypedRateLimitingInterface[string]
113
        vpcNatGwKeyMutex              keymutex.KeyMutex
114
        vpcNatGwExecKeyMutex          keymutex.KeyMutex
115

116
        vpcEgressGatewayLister           kubeovnlister.VpcEgressGatewayLister
117
        vpcEgressGatewaySynced           cache.InformerSynced
118
        addOrUpdateVpcEgressGatewayQueue workqueue.TypedRateLimitingInterface[string]
119
        delVpcEgressGatewayQueue         workqueue.TypedRateLimitingInterface[string]
120
        vpcEgressGatewayKeyMutex         keymutex.KeyMutex
121

122
        // bgpConfLister/evpnConfLister are published asynchronously by the
123
        // optional-CRD background poller (StartBgpEvpnConfInformerFactory), but
124
        // read by VEG worker goroutines. Atomic pointers keep the read/write
125
        // race-free without locking the hot reconcile path.
126
        bgpConfLister  atomic.Pointer[kubeovnlister.BgpConfLister]
127
        bgpConfSynced  cache.InformerSynced
128
        evpnConfLister atomic.Pointer[kubeovnlister.EvpnConfLister]
129
        evpnConfSynced cache.InformerSynced
130

131
        switchLBRuleLister      kubeovnlister.SwitchLBRuleLister
132
        switchLBRuleSynced      cache.InformerSynced
133
        addSwitchLBRuleQueue    workqueue.TypedRateLimitingInterface[string]
134
        updateSwitchLBRuleQueue workqueue.TypedRateLimitingInterface[*SlrInfo]
135
        delSwitchLBRuleQueue    workqueue.TypedRateLimitingInterface[*SlrInfo]
136

137
        vpcDNSLister           kubeovnlister.VpcDnsLister
138
        vpcDNSSynced           cache.InformerSynced
139
        addOrUpdateVpcDNSQueue workqueue.TypedRateLimitingInterface[string]
140
        delVpcDNSQueue         workqueue.TypedRateLimitingInterface[string]
141

142
        subnetsLister           kubeovnlister.SubnetLister
143
        subnetSynced            cache.InformerSynced
144
        addOrUpdateSubnetQueue  workqueue.TypedRateLimitingInterface[string]
145
        deleteSubnetQueue       workqueue.TypedRateLimitingInterface[*kubeovnv1.Subnet]
146
        updateSubnetStatusQueue workqueue.TypedRateLimitingInterface[string]
147
        syncVirtualPortsQueue   workqueue.TypedRateLimitingInterface[string]
148
        subnetKeyMutex          keymutex.KeyMutex
149

150
        ippoolLister            kubeovnlister.IPPoolLister
151
        ippoolSynced            cache.InformerSynced
152
        addOrUpdateIPPoolQueue  workqueue.TypedRateLimitingInterface[string]
153
        updateIPPoolStatusQueue workqueue.TypedRateLimitingInterface[string]
154
        deleteIPPoolQueue       workqueue.TypedRateLimitingInterface[*kubeovnv1.IPPool]
155
        ippoolKeyMutex          keymutex.KeyMutex
156

157
        ipsLister     kubeovnlister.IPLister
158
        ipSynced      cache.InformerSynced
159
        addIPQueue    workqueue.TypedRateLimitingInterface[string]
160
        updateIPQueue workqueue.TypedRateLimitingInterface[string]
161
        delIPQueue    workqueue.TypedRateLimitingInterface[*kubeovnv1.IP]
162

163
        virtualIpsLister          kubeovnlister.VipLister
164
        virtualIpsSynced          cache.InformerSynced
165
        addVirtualIPQueue         workqueue.TypedRateLimitingInterface[string]
166
        updateVirtualIPQueue      workqueue.TypedRateLimitingInterface[string]
167
        updateVirtualParentsQueue workqueue.TypedRateLimitingInterface[string]
168
        delVirtualIPQueue         workqueue.TypedRateLimitingInterface[*kubeovnv1.Vip]
169

170
        iptablesEipsLister     kubeovnlister.IptablesEIPLister
171
        iptablesEipSynced      cache.InformerSynced
172
        addIptablesEipQueue    workqueue.TypedRateLimitingInterface[string]
173
        updateIptablesEipQueue workqueue.TypedRateLimitingInterface[string]
174
        resetIptablesEipQueue  workqueue.TypedRateLimitingInterface[string]
175
        delIptablesEipQueue    workqueue.TypedRateLimitingInterface[*kubeovnv1.IptablesEIP]
176

177
        iptablesFipsLister     kubeovnlister.IptablesFIPRuleLister
178
        iptablesFipSynced      cache.InformerSynced
179
        addIptablesFipQueue    workqueue.TypedRateLimitingInterface[string]
180
        updateIptablesFipQueue workqueue.TypedRateLimitingInterface[string]
181
        delIptablesFipQueue    workqueue.TypedRateLimitingInterface[string]
182

183
        iptablesDnatRulesLister     kubeovnlister.IptablesDnatRuleLister
184
        iptablesDnatRuleSynced      cache.InformerSynced
185
        addIptablesDnatRuleQueue    workqueue.TypedRateLimitingInterface[string]
186
        updateIptablesDnatRuleQueue workqueue.TypedRateLimitingInterface[string]
187
        delIptablesDnatRuleQueue    workqueue.TypedRateLimitingInterface[string]
188

189
        iptablesSnatRulesLister     kubeovnlister.IptablesSnatRuleLister
190
        iptablesSnatRuleSynced      cache.InformerSynced
191
        addIptablesSnatRuleQueue    workqueue.TypedRateLimitingInterface[string]
192
        updateIptablesSnatRuleQueue workqueue.TypedRateLimitingInterface[string]
193
        delIptablesSnatRuleQueue    workqueue.TypedRateLimitingInterface[string]
194

195
        ovnEipsLister     kubeovnlister.OvnEipLister
196
        ovnEipSynced      cache.InformerSynced
197
        addOvnEipQueue    workqueue.TypedRateLimitingInterface[string]
198
        updateOvnEipQueue workqueue.TypedRateLimitingInterface[string]
199
        resetOvnEipQueue  workqueue.TypedRateLimitingInterface[string]
200
        delOvnEipQueue    workqueue.TypedRateLimitingInterface[*kubeovnv1.OvnEip]
201

202
        ovnFipsLister     kubeovnlister.OvnFipLister
203
        ovnFipSynced      cache.InformerSynced
204
        addOvnFipQueue    workqueue.TypedRateLimitingInterface[string]
205
        updateOvnFipQueue workqueue.TypedRateLimitingInterface[string]
206
        delOvnFipQueue    workqueue.TypedRateLimitingInterface[string]
207

208
        ovnSnatRulesLister     kubeovnlister.OvnSnatRuleLister
209
        ovnSnatRuleSynced      cache.InformerSynced
210
        addOvnSnatRuleQueue    workqueue.TypedRateLimitingInterface[string]
211
        updateOvnSnatRuleQueue workqueue.TypedRateLimitingInterface[string]
212
        delOvnSnatRuleQueue    workqueue.TypedRateLimitingInterface[string]
213

214
        ovnDnatRulesLister     kubeovnlister.OvnDnatRuleLister
215
        ovnDnatRuleSynced      cache.InformerSynced
216
        addOvnDnatRuleQueue    workqueue.TypedRateLimitingInterface[string]
217
        updateOvnDnatRuleQueue workqueue.TypedRateLimitingInterface[string]
218
        delOvnDnatRuleQueue    workqueue.TypedRateLimitingInterface[string]
219

220
        providerNetworksLister kubeovnlister.ProviderNetworkLister
221
        providerNetworkSynced  cache.InformerSynced
222

223
        vlansLister     kubeovnlister.VlanLister
224
        vlanSynced      cache.InformerSynced
225
        addVlanQueue    workqueue.TypedRateLimitingInterface[string]
226
        delVlanQueue    workqueue.TypedRateLimitingInterface[string]
227
        updateVlanQueue workqueue.TypedRateLimitingInterface[string]
228
        vlanKeyMutex    keymutex.KeyMutex
229

230
        namespacesLister  v1.NamespaceLister
231
        namespacesSynced  cache.InformerSynced
232
        addNamespaceQueue workqueue.TypedRateLimitingInterface[string]
233
        nsKeyMutex        keymutex.KeyMutex
234

235
        nodesLister     v1.NodeLister
236
        nodesSynced     cache.InformerSynced
237
        addNodeQueue    workqueue.TypedRateLimitingInterface[string]
238
        updateNodeQueue workqueue.TypedRateLimitingInterface[string]
239
        deleteNodeQueue workqueue.TypedRateLimitingInterface[string]
240
        nodeKeyMutex    keymutex.KeyMutex
241

242
        servicesLister     v1.ServiceLister
243
        serviceSynced      cache.InformerSynced
244
        addServiceQueue    workqueue.TypedRateLimitingInterface[string]
245
        deleteServiceQueue workqueue.TypedRateLimitingInterface[*vpcService]
246
        updateServiceQueue workqueue.TypedRateLimitingInterface[*updateSvcObject]
247
        svcKeyMutex        keymutex.KeyMutex
248

249
        endpointSlicesLister          discoveryv1.EndpointSliceLister
250
        endpointSlicesSynced          cache.InformerSynced
251
        addOrUpdateEndpointSliceQueue workqueue.TypedRateLimitingInterface[string]
252
        epKeyMutex                    keymutex.KeyMutex
253

254
        deploymentsLister appsv1.DeploymentLister
255
        deploymentsSynced cache.InformerSynced
256

257
        npsLister     netv1.NetworkPolicyLister
258
        npsSynced     cache.InformerSynced
259
        updateNpQueue workqueue.TypedRateLimitingInterface[string]
260
        deleteNpQueue workqueue.TypedRateLimitingInterface[string]
261
        npKeyMutex    keymutex.KeyMutex
262

263
        sgsLister          kubeovnlister.SecurityGroupLister
264
        sgSynced           cache.InformerSynced
265
        addOrUpdateSgQueue workqueue.TypedRateLimitingInterface[string]
266
        delSgQueue         workqueue.TypedRateLimitingInterface[string]
267
        syncSgPortsQueue   workqueue.TypedRateLimitingInterface[string]
268
        sgKeyMutex         keymutex.KeyMutex
269

270
        qosPoliciesLister    kubeovnlister.QoSPolicyLister
271
        qosPolicySynced      cache.InformerSynced
272
        addQoSPolicyQueue    workqueue.TypedRateLimitingInterface[string]
273
        updateQoSPolicyQueue workqueue.TypedRateLimitingInterface[string]
274
        delQoSPolicyQueue    workqueue.TypedRateLimitingInterface[string]
275

276
        configMapsLister v1.ConfigMapLister
277
        configMapsSynced cache.InformerSynced
278

279
        anpsLister     anplister.AdminNetworkPolicyLister
280
        anpsSynced     cache.InformerSynced
281
        addAnpQueue    workqueue.TypedRateLimitingInterface[string]
282
        updateAnpQueue workqueue.TypedRateLimitingInterface[*AdminNetworkPolicyChangedDelta]
283
        deleteAnpQueue workqueue.TypedRateLimitingInterface[*v1alpha1.AdminNetworkPolicy]
284
        anpKeyMutex    keymutex.KeyMutex
285

286
        dnsNameResolversLister          kubeovnlister.DNSNameResolverLister
287
        dnsNameResolversSynced          cache.InformerSynced
288
        addOrUpdateDNSNameResolverQueue workqueue.TypedRateLimitingInterface[string]
289
        deleteDNSNameResolverQueue      workqueue.TypedRateLimitingInterface[*kubeovnv1.DNSNameResolver]
290

291
        banpsLister     anplister.BaselineAdminNetworkPolicyLister
292
        banpsSynced     cache.InformerSynced
293
        addBanpQueue    workqueue.TypedRateLimitingInterface[string]
294
        updateBanpQueue workqueue.TypedRateLimitingInterface[*AdminNetworkPolicyChangedDelta]
295
        deleteBanpQueue workqueue.TypedRateLimitingInterface[*v1alpha1.BaselineAdminNetworkPolicy]
296
        banpKeyMutex    keymutex.KeyMutex
297

298
        cnpsLister     anplisterv1alpha2.ClusterNetworkPolicyLister
299
        cnpsSynced     cache.InformerSynced
300
        addCnpQueue    workqueue.TypedRateLimitingInterface[string]
301
        updateCnpQueue workqueue.TypedRateLimitingInterface[*ClusterNetworkPolicyChangedDelta]
302
        deleteCnpQueue workqueue.TypedRateLimitingInterface[*netpolv1alpha2.ClusterNetworkPolicy]
303
        cnpKeyMutex    keymutex.KeyMutex
304

305
        csrLister           certListerv1.CertificateSigningRequestLister
306
        csrSynced           cache.InformerSynced
307
        addOrUpdateCsrQueue workqueue.TypedRateLimitingInterface[string]
308

309
        addOrUpdateVMIMigrationQueue workqueue.TypedRateLimitingInterface[string]
310
        deleteVMQueue                workqueue.TypedRateLimitingInterface[string]
311
        kubevirtInformerFactory      informer.KubeVirtInformerFactory
312

313
        netAttachLister          netAttachv1.NetworkAttachmentDefinitionLister
314
        netAttachSynced          cache.InformerSynced
315
        netAttachInformerFactory netAttach.SharedInformerFactory
316

317
        recorder               record.EventRecorder
318
        informerFactory        kubeinformers.SharedInformerFactory
319
        cmInformerFactory      kubeinformers.SharedInformerFactory
320
        deployInformerFactory  kubeinformers.SharedInformerFactory
321
        kubeovnInformerFactory kubeovninformer.SharedInformerFactory
322
        anpInformerFactory     anpinformer.SharedInformerFactory
323

324
        // Database health check
325
        dbFailureCount int
326

327
        distributedSubnetNeedSync atomic.Bool
328
}
329

330
func newTypedRateLimitingQueue[T comparable](name string, rateLimiter workqueue.TypedRateLimiter[T]) workqueue.TypedRateLimitingInterface[T] {
1✔
331
        if rateLimiter == nil {
2✔
332
                rateLimiter = workqueue.DefaultTypedControllerRateLimiter[T]()
1✔
333
        }
1✔
334
        return workqueue.NewTypedRateLimitingQueueWithConfig(rateLimiter, workqueue.TypedRateLimitingQueueConfig[T]{Name: name})
1✔
335
}
336

337
// Run creates and runs a new ovn controller
338
func Run(ctx context.Context, config *Configuration) {
×
339
        klog.V(4).Info("Creating event broadcaster")
×
340
        eventBroadcaster := record.NewBroadcasterWithCorrelatorOptions(record.CorrelatorOptions{BurstSize: 100})
×
341
        eventBroadcaster.StartLogging(klog.Infof)
×
342
        eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: config.KubeFactoryClient.CoreV1().Events(metav1.NamespaceAll)})
×
343
        recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: controllerAgentName})
×
344
        custCrdRateLimiter := workqueue.NewTypedMaxOfRateLimiter(
×
345
                workqueue.NewTypedItemExponentialFailureRateLimiter[string](time.Duration(config.CustCrdRetryMinDelay)*time.Second, time.Duration(config.CustCrdRetryMaxDelay)*time.Second),
×
346
                &workqueue.TypedBucketRateLimiter[string]{Limiter: rate.NewLimiter(rate.Limit(10), 100)},
×
347
        )
×
348

×
349
        selector, err := labels.Parse(util.VpcEgressGatewayLabel)
×
350
        if err != nil {
×
351
                util.LogFatalAndExit(err, "failed to create label selector for vpc egress gateway workload")
×
352
        }
×
353

354
        informerFactory := kubeinformers.NewSharedInformerFactoryWithOptions(config.KubeFactoryClient, 0,
×
355
                kubeinformers.WithTransform(util.TrimManagedFields),
×
356
                kubeinformers.WithTweakListOptions(func(listOption *metav1.ListOptions) {
×
357
                        listOption.AllowWatchBookmarks = true
×
358
                }))
×
359
        cmInformerFactory := kubeinformers.NewSharedInformerFactoryWithOptions(config.KubeFactoryClient, 0,
×
360
                kubeinformers.WithNamespace(config.PodNamespace),
×
361
                kubeinformers.WithTransform(util.TrimManagedFields),
×
362
                kubeinformers.WithTweakListOptions(func(listOption *metav1.ListOptions) {
×
363
                        listOption.AllowWatchBookmarks = true
×
364
                }))
×
365
        // deployment informer used to list/watch vpc egress gateway workloads
366
        deployInformerFactory := kubeinformers.NewSharedInformerFactoryWithOptions(config.KubeFactoryClient, 0,
×
367
                kubeinformers.WithTransform(util.TrimManagedFields),
×
368
                kubeinformers.WithTweakListOptions(func(listOption *metav1.ListOptions) {
×
369
                        listOption.AllowWatchBookmarks = true
×
370
                        listOption.LabelSelector = selector.String()
×
371
                }))
×
372
        kubeovnInformerFactory := kubeovninformer.NewSharedInformerFactoryWithOptions(config.KubeOvnFactoryClient, 0,
×
373
                kubeovninformer.WithTransform(util.TrimManagedFields),
×
374
                kubeovninformer.WithTweakListOptions(func(listOption *metav1.ListOptions) {
×
375
                        listOption.AllowWatchBookmarks = true
×
376
                }))
×
377
        anpInformerFactory := anpinformer.NewSharedInformerFactoryWithOptions(config.AnpClient, 0,
×
378
                anpinformer.WithTransform(util.TrimManagedFields),
×
379
                anpinformer.WithTweakListOptions(func(listOption *metav1.ListOptions) {
×
380
                        listOption.AllowWatchBookmarks = true
×
381
                }))
×
382
        attachNetInformerFactory := netAttach.NewSharedInformerFactoryWithOptions(config.AttachNetClient, 0,
×
383
                netAttach.WithTweakListOptions(func(listOption *metav1.ListOptions) {
×
384
                        listOption.AllowWatchBookmarks = true
×
385
                }),
×
386
        )
387
        kubevirtInformerFactory := informer.NewKubeVirtInformerFactoryWithOptions(config.KubevirtClient.RestClient(), config.KubevirtClient,
×
388
                informer.WithTransform(util.TrimManagedFields),
×
389
        )
×
390

×
391
        vpcInformer := kubeovnInformerFactory.Kubeovn().V1().Vpcs()
×
392
        vpcNatGatewayInformer := kubeovnInformerFactory.Kubeovn().V1().VpcNatGateways()
×
393
        vpcEgressGatewayInformer := kubeovnInformerFactory.Kubeovn().V1().VpcEgressGateways()
×
NEW
394
        // BgpConf/EvpnConf informers are started lazily via StartBgpEvpnConfInformerFactory
×
NEW
395
        // because their CRDs are optional on clusters that don't use vpc-egress-gateway BGP/EVPN.
×
396
        subnetInformer := kubeovnInformerFactory.Kubeovn().V1().Subnets()
×
397
        ippoolInformer := kubeovnInformerFactory.Kubeovn().V1().IPPools()
×
398
        ipInformer := kubeovnInformerFactory.Kubeovn().V1().IPs()
×
399
        virtualIPInformer := kubeovnInformerFactory.Kubeovn().V1().Vips()
×
400
        iptablesEipInformer := kubeovnInformerFactory.Kubeovn().V1().IptablesEIPs()
×
401
        iptablesFipInformer := kubeovnInformerFactory.Kubeovn().V1().IptablesFIPRules()
×
402
        iptablesDnatRuleInformer := kubeovnInformerFactory.Kubeovn().V1().IptablesDnatRules()
×
403
        iptablesSnatRuleInformer := kubeovnInformerFactory.Kubeovn().V1().IptablesSnatRules()
×
404
        vlanInformer := kubeovnInformerFactory.Kubeovn().V1().Vlans()
×
405
        providerNetworkInformer := kubeovnInformerFactory.Kubeovn().V1().ProviderNetworks()
×
406
        sgInformer := kubeovnInformerFactory.Kubeovn().V1().SecurityGroups()
×
407
        podInformer := informerFactory.Core().V1().Pods()
×
408
        namespaceInformer := informerFactory.Core().V1().Namespaces()
×
409
        nodeInformer := informerFactory.Core().V1().Nodes()
×
410
        serviceInformer := informerFactory.Core().V1().Services()
×
411
        endpointSliceInformer := informerFactory.Discovery().V1().EndpointSlices()
×
412
        deploymentInformer := deployInformerFactory.Apps().V1().Deployments()
×
413
        qosPolicyInformer := kubeovnInformerFactory.Kubeovn().V1().QoSPolicies()
×
414
        configMapInformer := cmInformerFactory.Core().V1().ConfigMaps()
×
415
        npInformer := informerFactory.Networking().V1().NetworkPolicies()
×
416
        switchLBRuleInformer := kubeovnInformerFactory.Kubeovn().V1().SwitchLBRules()
×
417
        vpcDNSInformer := kubeovnInformerFactory.Kubeovn().V1().VpcDnses()
×
418
        ovnEipInformer := kubeovnInformerFactory.Kubeovn().V1().OvnEips()
×
419
        ovnFipInformer := kubeovnInformerFactory.Kubeovn().V1().OvnFips()
×
420
        ovnSnatRuleInformer := kubeovnInformerFactory.Kubeovn().V1().OvnSnatRules()
×
421
        ovnDnatRuleInformer := kubeovnInformerFactory.Kubeovn().V1().OvnDnatRules()
×
422
        anpInformer := anpInformerFactory.Policy().V1alpha1().AdminNetworkPolicies()
×
423
        banpInformer := anpInformerFactory.Policy().V1alpha1().BaselineAdminNetworkPolicies()
×
424
        cnpInformer := anpInformerFactory.Policy().V1alpha2().ClusterNetworkPolicies()
×
425
        dnsNameResolverInformer := kubeovnInformerFactory.Kubeovn().V1().DNSNameResolvers()
×
426
        csrInformer := informerFactory.Certificates().V1().CertificateSigningRequests()
×
427
        netAttachInformer := attachNetInformerFactory.K8sCniCncfIo().V1().NetworkAttachmentDefinitions()
×
428

×
429
        numKeyLocks := max(runtime.NumCPU()*2, config.WorkerNum*2)
×
430
        controller := &Controller{
×
431
                config:             config,
×
432
                deletingPodObjMap:  xsync.NewMap[string, *corev1.Pod](),
×
433
                deletingNodeObjMap: xsync.NewMap[string, *corev1.Node](),
×
434
                ipam:               ovnipam.NewIPAM(),
×
435
                namedPort:          NewNamedPort(),
×
436

×
437
                vpcsLister:           vpcInformer.Lister(),
×
438
                vpcSynced:            vpcInformer.Informer().HasSynced,
×
439
                addOrUpdateVpcQueue:  newTypedRateLimitingQueue[string]("AddOrUpdateVpc", nil),
×
440
                vpcLastPoliciesMap:   xsync.NewMap[string, string](),
×
441
                delVpcQueue:          newTypedRateLimitingQueue[*kubeovnv1.Vpc]("DeleteVpc", nil),
×
442
                updateVpcStatusQueue: newTypedRateLimitingQueue[string]("UpdateVpcStatus", nil),
×
443
                vpcKeyMutex:          keymutex.NewHashed(numKeyLocks),
×
444

×
445
                vpcNatGatewayLister:              vpcNatGatewayInformer.Lister(),
×
446
                vpcNatGatewaySynced:              vpcNatGatewayInformer.Informer().HasSynced,
×
447
                addOrUpdateVpcNatGatewayQueue:    newTypedRateLimitingQueue("AddOrUpdateVpcNatGw", custCrdRateLimiter),
×
448
                initVpcNatGatewayQueue:           newTypedRateLimitingQueue("InitVpcNatGw", custCrdRateLimiter),
×
449
                delVpcNatGatewayQueue:            newTypedRateLimitingQueue("DeleteVpcNatGw", custCrdRateLimiter),
×
450
                updateVpcEipQueue:                newTypedRateLimitingQueue("UpdateVpcEip", custCrdRateLimiter),
×
451
                updateVpcFloatingIPQueue:         newTypedRateLimitingQueue("UpdateVpcFloatingIp", custCrdRateLimiter),
×
452
                updateVpcDnatQueue:               newTypedRateLimitingQueue("UpdateVpcDnat", custCrdRateLimiter),
×
453
                updateVpcSnatQueue:               newTypedRateLimitingQueue("UpdateVpcSnat", custCrdRateLimiter),
×
454
                updateVpcSubnetQueue:             newTypedRateLimitingQueue("UpdateVpcSubnet", custCrdRateLimiter),
×
455
                vpcNatGwKeyMutex:                 keymutex.NewHashed(numKeyLocks),
×
456
                vpcNatGwExecKeyMutex:             keymutex.NewHashed(numKeyLocks),
×
457
                vpcEgressGatewayLister:           vpcEgressGatewayInformer.Lister(),
×
458
                vpcEgressGatewaySynced:           vpcEgressGatewayInformer.Informer().HasSynced,
×
459
                addOrUpdateVpcEgressGatewayQueue: newTypedRateLimitingQueue("AddOrUpdateVpcEgressGateway", custCrdRateLimiter),
×
460
                delVpcEgressGatewayQueue:         newTypedRateLimitingQueue("DeleteVpcEgressGateway", custCrdRateLimiter),
×
461
                vpcEgressGatewayKeyMutex:         keymutex.NewHashed(numKeyLocks),
×
462

×
NEW
463
                // bgpConfLister/bgpConfSynced/evpnConfLister/evpnConfSynced are populated lazily
×
NEW
464
                // in startBgpEvpnConfInformer once the matching CRDs are detected.
×
465

×
466
                subnetsLister:           subnetInformer.Lister(),
×
467
                subnetSynced:            subnetInformer.Informer().HasSynced,
×
468
                addOrUpdateSubnetQueue:  newTypedRateLimitingQueue[string]("AddSubnet", nil),
×
469
                deleteSubnetQueue:       newTypedRateLimitingQueue[*kubeovnv1.Subnet]("DeleteSubnet", nil),
×
470
                updateSubnetStatusQueue: newTypedRateLimitingQueue[string]("UpdateSubnetStatus", nil),
×
471
                syncVirtualPortsQueue:   newTypedRateLimitingQueue[string]("SyncVirtualPort", nil),
×
472
                subnetKeyMutex:          keymutex.NewHashed(numKeyLocks),
×
473

×
474
                ippoolLister:            ippoolInformer.Lister(),
×
475
                ippoolSynced:            ippoolInformer.Informer().HasSynced,
×
476
                addOrUpdateIPPoolQueue:  newTypedRateLimitingQueue[string]("AddIPPool", nil),
×
477
                updateIPPoolStatusQueue: newTypedRateLimitingQueue[string]("UpdateIPPoolStatus", nil),
×
478
                deleteIPPoolQueue:       newTypedRateLimitingQueue[*kubeovnv1.IPPool]("DeleteIPPool", nil),
×
479
                ippoolKeyMutex:          keymutex.NewHashed(numKeyLocks),
×
480

×
481
                ipsLister:     ipInformer.Lister(),
×
482
                ipSynced:      ipInformer.Informer().HasSynced,
×
483
                addIPQueue:    newTypedRateLimitingQueue[string]("AddIP", nil),
×
484
                updateIPQueue: newTypedRateLimitingQueue[string]("UpdateIP", nil),
×
485
                delIPQueue:    newTypedRateLimitingQueue[*kubeovnv1.IP]("DeleteIP", nil),
×
486

×
487
                virtualIpsLister:          virtualIPInformer.Lister(),
×
488
                virtualIpsSynced:          virtualIPInformer.Informer().HasSynced,
×
489
                addVirtualIPQueue:         newTypedRateLimitingQueue[string]("AddVirtualIP", nil),
×
490
                updateVirtualIPQueue:      newTypedRateLimitingQueue[string]("UpdateVirtualIP", nil),
×
491
                updateVirtualParentsQueue: newTypedRateLimitingQueue[string]("UpdateVirtualParents", nil),
×
492
                delVirtualIPQueue:         newTypedRateLimitingQueue[*kubeovnv1.Vip]("DeleteVirtualIP", nil),
×
493

×
494
                iptablesEipsLister:     iptablesEipInformer.Lister(),
×
495
                iptablesEipSynced:      iptablesEipInformer.Informer().HasSynced,
×
496
                addIptablesEipQueue:    newTypedRateLimitingQueue("AddIptablesEip", custCrdRateLimiter),
×
497
                updateIptablesEipQueue: newTypedRateLimitingQueue("UpdateIptablesEip", custCrdRateLimiter),
×
498
                resetIptablesEipQueue:  newTypedRateLimitingQueue("ResetIptablesEip", custCrdRateLimiter),
×
499
                delIptablesEipQueue:    newTypedRateLimitingQueue[*kubeovnv1.IptablesEIP]("DeleteIptablesEip", nil),
×
500

×
501
                iptablesFipsLister:     iptablesFipInformer.Lister(),
×
502
                iptablesFipSynced:      iptablesFipInformer.Informer().HasSynced,
×
503
                addIptablesFipQueue:    newTypedRateLimitingQueue("AddIptablesFip", custCrdRateLimiter),
×
504
                updateIptablesFipQueue: newTypedRateLimitingQueue("UpdateIptablesFip", custCrdRateLimiter),
×
505
                delIptablesFipQueue:    newTypedRateLimitingQueue("DeleteIptablesFip", custCrdRateLimiter),
×
506

×
507
                iptablesDnatRulesLister:     iptablesDnatRuleInformer.Lister(),
×
508
                iptablesDnatRuleSynced:      iptablesDnatRuleInformer.Informer().HasSynced,
×
509
                addIptablesDnatRuleQueue:    newTypedRateLimitingQueue("AddIptablesDnatRule", custCrdRateLimiter),
×
510
                updateIptablesDnatRuleQueue: newTypedRateLimitingQueue("UpdateIptablesDnatRule", custCrdRateLimiter),
×
511
                delIptablesDnatRuleQueue:    newTypedRateLimitingQueue("DeleteIptablesDnatRule", custCrdRateLimiter),
×
512

×
513
                iptablesSnatRulesLister:     iptablesSnatRuleInformer.Lister(),
×
514
                iptablesSnatRuleSynced:      iptablesSnatRuleInformer.Informer().HasSynced,
×
515
                addIptablesSnatRuleQueue:    newTypedRateLimitingQueue("AddIptablesSnatRule", custCrdRateLimiter),
×
516
                updateIptablesSnatRuleQueue: newTypedRateLimitingQueue("UpdateIptablesSnatRule", custCrdRateLimiter),
×
517
                delIptablesSnatRuleQueue:    newTypedRateLimitingQueue("DeleteIptablesSnatRule", custCrdRateLimiter),
×
518

×
519
                vlansLister:     vlanInformer.Lister(),
×
520
                vlanSynced:      vlanInformer.Informer().HasSynced,
×
521
                addVlanQueue:    newTypedRateLimitingQueue[string]("AddVlan", nil),
×
522
                delVlanQueue:    newTypedRateLimitingQueue[string]("DeleteVlan", nil),
×
523
                updateVlanQueue: newTypedRateLimitingQueue[string]("UpdateVlan", nil),
×
524
                vlanKeyMutex:    keymutex.NewHashed(numKeyLocks),
×
525

×
526
                providerNetworksLister: providerNetworkInformer.Lister(),
×
527
                providerNetworkSynced:  providerNetworkInformer.Informer().HasSynced,
×
528

×
529
                podsLister:          podInformer.Lister(),
×
530
                podsSynced:          podInformer.Informer().HasSynced,
×
531
                addOrUpdatePodQueue: newTypedRateLimitingQueue[string]("AddOrUpdatePod", nil),
×
532
                deletePodQueue: workqueue.NewTypedRateLimitingQueueWithConfig(
×
533
                        workqueue.DefaultTypedControllerRateLimiter[string](),
×
534
                        workqueue.TypedRateLimitingQueueConfig[string]{
×
535
                                Name:          "DeletePod",
×
536
                                DelayingQueue: workqueue.NewTypedDelayingQueue[string](),
×
537
                        },
×
538
                ),
×
539
                updatePodSecurityQueue: newTypedRateLimitingQueue[string]("UpdatePodSecurity", nil),
×
540
                podKeyMutex:            keymutex.NewHashed(numKeyLocks),
×
541

×
542
                namespacesLister:  namespaceInformer.Lister(),
×
543
                namespacesSynced:  namespaceInformer.Informer().HasSynced,
×
544
                addNamespaceQueue: newTypedRateLimitingQueue[string]("AddNamespace", nil),
×
545
                nsKeyMutex:        keymutex.NewHashed(numKeyLocks),
×
546

×
547
                nodesLister:     nodeInformer.Lister(),
×
548
                nodesSynced:     nodeInformer.Informer().HasSynced,
×
549
                addNodeQueue:    newTypedRateLimitingQueue[string]("AddNode", nil),
×
550
                updateNodeQueue: newTypedRateLimitingQueue[string]("UpdateNode", nil),
×
551
                deleteNodeQueue: newTypedRateLimitingQueue[string]("DeleteNode", nil),
×
552
                nodeKeyMutex:    keymutex.NewHashed(numKeyLocks),
×
553

×
554
                servicesLister:     serviceInformer.Lister(),
×
555
                serviceSynced:      serviceInformer.Informer().HasSynced,
×
556
                addServiceQueue:    newTypedRateLimitingQueue[string]("AddService", nil),
×
557
                deleteServiceQueue: newTypedRateLimitingQueue[*vpcService]("DeleteService", nil),
×
558
                updateServiceQueue: newTypedRateLimitingQueue[*updateSvcObject]("UpdateService", nil),
×
559
                svcKeyMutex:        keymutex.NewHashed(numKeyLocks),
×
560

×
561
                endpointSlicesLister:          endpointSliceInformer.Lister(),
×
562
                endpointSlicesSynced:          endpointSliceInformer.Informer().HasSynced,
×
563
                addOrUpdateEndpointSliceQueue: newTypedRateLimitingQueue[string]("UpdateEndpointSlice", nil),
×
564
                epKeyMutex:                    keymutex.NewHashed(numKeyLocks),
×
565

×
566
                deploymentsLister: deploymentInformer.Lister(),
×
567
                deploymentsSynced: deploymentInformer.Informer().HasSynced,
×
568

×
569
                qosPoliciesLister:    qosPolicyInformer.Lister(),
×
570
                qosPolicySynced:      qosPolicyInformer.Informer().HasSynced,
×
571
                addQoSPolicyQueue:    newTypedRateLimitingQueue("AddQoSPolicy", custCrdRateLimiter),
×
572
                updateQoSPolicyQueue: newTypedRateLimitingQueue("UpdateQoSPolicy", custCrdRateLimiter),
×
573
                delQoSPolicyQueue:    newTypedRateLimitingQueue("DeleteQoSPolicy", custCrdRateLimiter),
×
574

×
575
                configMapsLister: configMapInformer.Lister(),
×
576
                configMapsSynced: configMapInformer.Informer().HasSynced,
×
577

×
578
                sgKeyMutex:         keymutex.NewHashed(numKeyLocks),
×
579
                sgsLister:          sgInformer.Lister(),
×
580
                sgSynced:           sgInformer.Informer().HasSynced,
×
581
                addOrUpdateSgQueue: newTypedRateLimitingQueue[string]("UpdateSecurityGroup", nil),
×
582
                delSgQueue:         newTypedRateLimitingQueue[string]("DeleteSecurityGroup", nil),
×
583
                syncSgPortsQueue:   newTypedRateLimitingQueue[string]("SyncSecurityGroupPorts", nil),
×
584

×
585
                ovnEipsLister:     ovnEipInformer.Lister(),
×
586
                ovnEipSynced:      ovnEipInformer.Informer().HasSynced,
×
587
                addOvnEipQueue:    newTypedRateLimitingQueue("AddOvnEip", custCrdRateLimiter),
×
588
                updateOvnEipQueue: newTypedRateLimitingQueue("UpdateOvnEip", custCrdRateLimiter),
×
589
                resetOvnEipQueue:  newTypedRateLimitingQueue("ResetOvnEip", custCrdRateLimiter),
×
590
                delOvnEipQueue:    newTypedRateLimitingQueue[*kubeovnv1.OvnEip]("DeleteOvnEip", nil),
×
591

×
592
                ovnFipsLister:     ovnFipInformer.Lister(),
×
593
                ovnFipSynced:      ovnFipInformer.Informer().HasSynced,
×
594
                addOvnFipQueue:    newTypedRateLimitingQueue("AddOvnFip", custCrdRateLimiter),
×
595
                updateOvnFipQueue: newTypedRateLimitingQueue("UpdateOvnFip", custCrdRateLimiter),
×
596
                delOvnFipQueue:    newTypedRateLimitingQueue("DeleteOvnFip", custCrdRateLimiter),
×
597

×
598
                ovnSnatRulesLister:     ovnSnatRuleInformer.Lister(),
×
599
                ovnSnatRuleSynced:      ovnSnatRuleInformer.Informer().HasSynced,
×
600
                addOvnSnatRuleQueue:    newTypedRateLimitingQueue("AddOvnSnatRule", custCrdRateLimiter),
×
601
                updateOvnSnatRuleQueue: newTypedRateLimitingQueue("UpdateOvnSnatRule", custCrdRateLimiter),
×
602
                delOvnSnatRuleQueue:    newTypedRateLimitingQueue("DeleteOvnSnatRule", custCrdRateLimiter),
×
603

×
604
                ovnDnatRulesLister:     ovnDnatRuleInformer.Lister(),
×
605
                ovnDnatRuleSynced:      ovnDnatRuleInformer.Informer().HasSynced,
×
606
                addOvnDnatRuleQueue:    newTypedRateLimitingQueue("AddOvnDnatRule", custCrdRateLimiter),
×
607
                updateOvnDnatRuleQueue: newTypedRateLimitingQueue("UpdateOvnDnatRule", custCrdRateLimiter),
×
608
                delOvnDnatRuleQueue:    newTypedRateLimitingQueue("DeleteOvnDnatRule", custCrdRateLimiter),
×
609

×
610
                csrLister:           csrInformer.Lister(),
×
611
                csrSynced:           csrInformer.Informer().HasSynced,
×
612
                addOrUpdateCsrQueue: newTypedRateLimitingQueue("AddOrUpdateCSR", custCrdRateLimiter),
×
613

×
614
                addOrUpdateVMIMigrationQueue: newTypedRateLimitingQueue[string]("AddOrUpdateVMIMigration", nil),
×
615
                deleteVMQueue:                newTypedRateLimitingQueue[string]("DeleteVM", nil),
×
616
                kubevirtInformerFactory:      kubevirtInformerFactory,
×
617

×
618
                netAttachLister:          netAttachInformer.Lister(),
×
619
                netAttachSynced:          netAttachInformer.Informer().HasSynced,
×
620
                netAttachInformerFactory: attachNetInformerFactory,
×
621

×
622
                recorder:               recorder,
×
623
                informerFactory:        informerFactory,
×
624
                cmInformerFactory:      cmInformerFactory,
×
625
                deployInformerFactory:  deployInformerFactory,
×
626
                kubeovnInformerFactory: kubeovnInformerFactory,
×
627
                anpInformerFactory:     anpInformerFactory,
×
628
        }
×
629

×
630
        if controller.OVNNbClient, err = ovs.NewOvnNbClient(
×
631
                config.OvnNbAddr,
×
632
                config.OvnTimeout,
×
633
                config.OvsDbConnectTimeout,
×
634
                config.OvsDbInactivityTimeout,
×
635
                config.OvsDbConnectMaxRetry,
×
636
        ); err != nil {
×
637
                util.LogFatalAndExit(err, "failed to create ovn nb client")
×
638
        }
×
639
        if controller.OVNSbClient, err = ovs.NewOvnSbClient(
×
640
                config.OvnSbAddr,
×
641
                config.OvnTimeout,
×
642
                config.OvsDbConnectTimeout,
×
643
                config.OvsDbInactivityTimeout,
×
644
                config.OvsDbConnectMaxRetry,
×
645
        ); err != nil {
×
646
                util.LogFatalAndExit(err, "failed to create ovn sb client")
×
647
        }
×
648
        if config.EnableLb {
×
649
                controller.switchLBRuleLister = switchLBRuleInformer.Lister()
×
650
                controller.switchLBRuleSynced = switchLBRuleInformer.Informer().HasSynced
×
651
                controller.addSwitchLBRuleQueue = newTypedRateLimitingQueue("AddSwitchLBRule", custCrdRateLimiter)
×
652
                controller.delSwitchLBRuleQueue = newTypedRateLimitingQueue(
×
653
                        "DeleteSwitchLBRule",
×
654
                        workqueue.NewTypedMaxOfRateLimiter(
×
655
                                workqueue.NewTypedItemExponentialFailureRateLimiter[*SlrInfo](time.Duration(config.CustCrdRetryMinDelay)*time.Second, time.Duration(config.CustCrdRetryMaxDelay)*time.Second),
×
656
                                &workqueue.TypedBucketRateLimiter[*SlrInfo]{Limiter: rate.NewLimiter(rate.Limit(10), 100)},
×
657
                        ),
×
658
                )
×
659
                controller.updateSwitchLBRuleQueue = newTypedRateLimitingQueue(
×
660
                        "UpdateSwitchLBRule",
×
661
                        workqueue.NewTypedMaxOfRateLimiter(
×
662
                                workqueue.NewTypedItemExponentialFailureRateLimiter[*SlrInfo](time.Duration(config.CustCrdRetryMinDelay)*time.Second, time.Duration(config.CustCrdRetryMaxDelay)*time.Second),
×
663
                                &workqueue.TypedBucketRateLimiter[*SlrInfo]{Limiter: rate.NewLimiter(rate.Limit(10), 100)},
×
664
                        ),
×
665
                )
×
666

×
667
                controller.vpcDNSLister = vpcDNSInformer.Lister()
×
668
                controller.vpcDNSSynced = vpcDNSInformer.Informer().HasSynced
×
669
                controller.addOrUpdateVpcDNSQueue = newTypedRateLimitingQueue("AddOrUpdateVpcDns", custCrdRateLimiter)
×
670
                controller.delVpcDNSQueue = newTypedRateLimitingQueue("DeleteVpcDns", custCrdRateLimiter)
×
671
        }
×
672

673
        if config.EnableNP {
×
674
                controller.npsLister = npInformer.Lister()
×
675
                controller.npsSynced = npInformer.Informer().HasSynced
×
676
                controller.updateNpQueue = newTypedRateLimitingQueue[string]("UpdateNetworkPolicy", nil)
×
677
                controller.deleteNpQueue = newTypedRateLimitingQueue[string]("DeleteNetworkPolicy", nil)
×
678
                controller.npKeyMutex = keymutex.NewHashed(numKeyLocks)
×
679
        }
×
680

681
        if config.EnableANP {
×
682
                controller.anpsLister = anpInformer.Lister()
×
683
                controller.anpsSynced = anpInformer.Informer().HasSynced
×
684
                controller.addAnpQueue = newTypedRateLimitingQueue[string]("AddAdminNetworkPolicy", nil)
×
685
                controller.updateAnpQueue = newTypedRateLimitingQueue[*AdminNetworkPolicyChangedDelta]("UpdateAdminNetworkPolicy", nil)
×
686
                controller.deleteAnpQueue = newTypedRateLimitingQueue[*v1alpha1.AdminNetworkPolicy]("DeleteAdminNetworkPolicy", nil)
×
687
                controller.anpKeyMutex = keymutex.NewHashed(numKeyLocks)
×
688

×
689
                controller.banpsLister = banpInformer.Lister()
×
690
                controller.banpsSynced = banpInformer.Informer().HasSynced
×
691
                controller.addBanpQueue = newTypedRateLimitingQueue[string]("AddBaseAdminNetworkPolicy", nil)
×
692
                controller.updateBanpQueue = newTypedRateLimitingQueue[*AdminNetworkPolicyChangedDelta]("UpdateBaseAdminNetworkPolicy", nil)
×
693
                controller.deleteBanpQueue = newTypedRateLimitingQueue[*v1alpha1.BaselineAdminNetworkPolicy]("DeleteBaseAdminNetworkPolicy", nil)
×
694
                controller.banpKeyMutex = keymutex.NewHashed(numKeyLocks)
×
695

×
696
                controller.cnpsLister = cnpInformer.Lister()
×
697
                controller.cnpsSynced = cnpInformer.Informer().HasSynced
×
698
                controller.addCnpQueue = newTypedRateLimitingQueue[string]("AddClusterNetworkPolicy", nil)
×
699
                controller.updateCnpQueue = newTypedRateLimitingQueue[*ClusterNetworkPolicyChangedDelta]("UpdateClusterNetworkPolicy", nil)
×
700
                controller.deleteCnpQueue = newTypedRateLimitingQueue[*netpolv1alpha2.ClusterNetworkPolicy]("DeleteClusterNetworkPolicy", nil)
×
701
                controller.cnpKeyMutex = keymutex.NewHashed(numKeyLocks)
×
702
        }
×
703

704
        if config.EnableDNSNameResolver {
×
705
                controller.dnsNameResolversLister = dnsNameResolverInformer.Lister()
×
706
                controller.dnsNameResolversSynced = dnsNameResolverInformer.Informer().HasSynced
×
707
                controller.addOrUpdateDNSNameResolverQueue = newTypedRateLimitingQueue[string]("AddOrUpdateDNSNameResolver", nil)
×
708
                controller.deleteDNSNameResolverQueue = newTypedRateLimitingQueue[*kubeovnv1.DNSNameResolver]("DeleteDNSNameResolver", nil)
×
709
        }
×
710

711
        defer controller.shutdown()
×
712
        klog.Info("Starting OVN controller")
×
713

×
714
        // Start and sync NAD informer first, as many resources depend on NAD cache
×
715
        // NAD CRD is optional, so we check if it exists before starting the informer
×
716
        controller.StartNetAttachInformerFactory(ctx)
×
717

×
NEW
718
        // BgpConf/EvpnConf are optional CRDs (v1.16.0+, used by vpc-egress-gateway BGP/EVPN).
×
NEW
719
        // They may be missing on clusters upgraded from <v1.16 via Helm, which does not
×
NEW
720
        // re-apply the `crds/` directory on `helm upgrade`. Best-effort start with periodic retry.
×
NEW
721
        controller.StartBgpEvpnConfInformerFactory(ctx)
×
NEW
722

×
723
        // Wait for the caches to be synced before starting workers
×
724
        controller.informerFactory.Start(ctx.Done())
×
725
        controller.cmInformerFactory.Start(ctx.Done())
×
726
        controller.deployInformerFactory.Start(ctx.Done())
×
727
        controller.kubeovnInformerFactory.Start(ctx.Done())
×
728
        controller.anpInformerFactory.Start(ctx.Done())
×
729
        controller.StartKubevirtInformerFactory(ctx, kubevirtInformerFactory)
×
730

×
731
        klog.Info("Waiting for informer caches to sync")
×
732
        cacheSyncs := []cache.InformerSynced{
×
733
                controller.vpcNatGatewaySynced, controller.vpcEgressGatewaySynced,
×
734
                controller.vpcSynced, controller.subnetSynced,
×
735
                controller.ipSynced, controller.virtualIpsSynced, controller.iptablesEipSynced,
×
736
                controller.iptablesFipSynced, controller.iptablesDnatRuleSynced, controller.iptablesSnatRuleSynced,
×
737
                controller.vlanSynced, controller.podsSynced, controller.namespacesSynced, controller.nodesSynced,
×
738
                controller.serviceSynced, controller.endpointSlicesSynced, controller.deploymentsSynced, controller.configMapsSynced,
×
739
                controller.ovnEipSynced, controller.ovnFipSynced, controller.ovnSnatRuleSynced,
×
740
                controller.ovnDnatRuleSynced,
×
741
        }
×
742
        if controller.config.EnableLb {
×
743
                cacheSyncs = append(cacheSyncs, controller.switchLBRuleSynced, controller.vpcDNSSynced)
×
744
        }
×
745
        if controller.config.EnableNP {
×
746
                cacheSyncs = append(cacheSyncs, controller.npsSynced)
×
747
        }
×
748
        if controller.config.EnableANP {
×
749
                cacheSyncs = append(cacheSyncs, controller.anpsSynced, controller.banpsSynced, controller.cnpsSynced)
×
750
        }
×
751
        if controller.config.EnableDNSNameResolver {
×
752
                cacheSyncs = append(cacheSyncs, controller.dnsNameResolversSynced)
×
753
        }
×
754

755
        if !cache.WaitForCacheSync(ctx.Done(), cacheSyncs...) {
×
756
                util.LogFatalAndExit(nil, "failed to wait for caches to sync")
×
757
        }
×
758

759
        if _, err = podInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
760
                AddFunc:    controller.enqueueAddPod,
×
761
                DeleteFunc: controller.enqueueDeletePod,
×
762
                UpdateFunc: controller.enqueueUpdatePod,
×
763
        }); err != nil {
×
764
                util.LogFatalAndExit(err, "failed to add pod event handler")
×
765
        }
×
766

767
        if _, err = namespaceInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
768
                AddFunc:    controller.enqueueAddNamespace,
×
769
                UpdateFunc: controller.enqueueUpdateNamespace,
×
770
                DeleteFunc: controller.enqueueDeleteNamespace,
×
771
        }); err != nil {
×
772
                util.LogFatalAndExit(err, "failed to add namespace event handler")
×
773
        }
×
774

775
        if _, err = nodeInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
776
                AddFunc:    controller.enqueueAddNode,
×
777
                UpdateFunc: controller.enqueueUpdateNode,
×
778
                DeleteFunc: controller.enqueueDeleteNode,
×
779
        }); err != nil {
×
780
                util.LogFatalAndExit(err, "failed to add node event handler")
×
781
        }
×
782

783
        if _, err = serviceInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
784
                AddFunc:    controller.enqueueAddService,
×
785
                DeleteFunc: controller.enqueueDeleteService,
×
786
                UpdateFunc: controller.enqueueUpdateService,
×
787
        }); err != nil {
×
788
                util.LogFatalAndExit(err, "failed to add service event handler")
×
789
        }
×
790

791
        if _, err = endpointSliceInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
792
                AddFunc:    controller.enqueueAddEndpointSlice,
×
793
                UpdateFunc: controller.enqueueUpdateEndpointSlice,
×
794
        }); err != nil {
×
795
                util.LogFatalAndExit(err, "failed to add endpoint slice event handler")
×
796
        }
×
797

798
        if _, err = deploymentInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
799
                AddFunc:    controller.enqueueAddDeployment,
×
800
                UpdateFunc: controller.enqueueUpdateDeployment,
×
801
        }); err != nil {
×
802
                util.LogFatalAndExit(err, "failed to add deployment event handler")
×
803
        }
×
804

805
        if _, err = vpcInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
806
                AddFunc:    controller.enqueueAddVpc,
×
807
                UpdateFunc: controller.enqueueUpdateVpc,
×
808
                DeleteFunc: controller.enqueueDelVpc,
×
809
        }); err != nil {
×
810
                util.LogFatalAndExit(err, "failed to add vpc event handler")
×
811
        }
×
812

813
        if _, err = vpcNatGatewayInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
814
                AddFunc:    controller.enqueueAddVpcNatGw,
×
815
                UpdateFunc: controller.enqueueUpdateVpcNatGw,
×
816
                DeleteFunc: controller.enqueueDeleteVpcNatGw,
×
817
        }); err != nil {
×
818
                util.LogFatalAndExit(err, "failed to add vpc nat gateway event handler")
×
819
        }
×
820

821
        if _, err = vpcEgressGatewayInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
822
                AddFunc:    controller.enqueueAddVpcEgressGateway,
×
823
                UpdateFunc: controller.enqueueUpdateVpcEgressGateway,
×
824
                DeleteFunc: controller.enqueueDeleteVpcEgressGateway,
×
825
        }); err != nil {
×
826
                util.LogFatalAndExit(err, "failed to add vpc egress gateway event handler")
×
827
        }
×
828

829
        if _, err = subnetInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
830
                AddFunc:    controller.enqueueAddSubnet,
×
831
                UpdateFunc: controller.enqueueUpdateSubnet,
×
832
                DeleteFunc: controller.enqueueDeleteSubnet,
×
833
        }); err != nil {
×
834
                util.LogFatalAndExit(err, "failed to add subnet event handler")
×
835
        }
×
836

837
        if _, err = ippoolInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
838
                AddFunc:    controller.enqueueAddIPPool,
×
839
                UpdateFunc: controller.enqueueUpdateIPPool,
×
840
                DeleteFunc: controller.enqueueDeleteIPPool,
×
841
        }); err != nil {
×
842
                util.LogFatalAndExit(err, "failed to add ippool event handler")
×
843
        }
×
844

845
        if _, err = ipInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
846
                AddFunc:    controller.enqueueAddIP,
×
847
                UpdateFunc: controller.enqueueUpdateIP,
×
848
                DeleteFunc: controller.enqueueDelIP,
×
849
        }); err != nil {
×
850
                util.LogFatalAndExit(err, "failed to add ips event handler")
×
851
        }
×
852

853
        if _, err = vlanInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
854
                AddFunc:    controller.enqueueAddVlan,
×
855
                DeleteFunc: controller.enqueueDelVlan,
×
856
                UpdateFunc: controller.enqueueUpdateVlan,
×
857
        }); err != nil {
×
858
                util.LogFatalAndExit(err, "failed to add vlan event handler")
×
859
        }
×
860

861
        if _, err = sgInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
862
                AddFunc:    controller.enqueueAddSg,
×
863
                DeleteFunc: controller.enqueueDeleteSg,
×
864
                UpdateFunc: controller.enqueueUpdateSg,
×
865
        }); err != nil {
×
866
                util.LogFatalAndExit(err, "failed to add security group event handler")
×
867
        }
×
868

869
        if _, err = virtualIPInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
870
                AddFunc:    controller.enqueueAddVirtualIP,
×
871
                UpdateFunc: controller.enqueueUpdateVirtualIP,
×
872
                DeleteFunc: controller.enqueueDelVirtualIP,
×
873
        }); err != nil {
×
874
                util.LogFatalAndExit(err, "failed to add virtual ip event handler")
×
875
        }
×
876

877
        if _, err = iptablesEipInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
878
                AddFunc:    controller.enqueueAddIptablesEip,
×
879
                UpdateFunc: controller.enqueueUpdateIptablesEip,
×
880
                DeleteFunc: controller.enqueueDelIptablesEip,
×
881
        }); err != nil {
×
882
                util.LogFatalAndExit(err, "failed to add iptables eip event handler")
×
883
        }
×
884

885
        if _, err = iptablesFipInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
886
                AddFunc:    controller.enqueueAddIptablesFip,
×
887
                UpdateFunc: controller.enqueueUpdateIptablesFip,
×
888
                DeleteFunc: controller.enqueueDelIptablesFip,
×
889
        }); err != nil {
×
890
                util.LogFatalAndExit(err, "failed to add iptables fip event handler")
×
891
        }
×
892

893
        if _, err = iptablesDnatRuleInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
894
                AddFunc:    controller.enqueueAddIptablesDnatRule,
×
895
                UpdateFunc: controller.enqueueUpdateIptablesDnatRule,
×
896
                DeleteFunc: controller.enqueueDelIptablesDnatRule,
×
897
        }); err != nil {
×
898
                util.LogFatalAndExit(err, "failed to add iptables dnat event handler")
×
899
        }
×
900

901
        if _, err = iptablesSnatRuleInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
902
                AddFunc:    controller.enqueueAddIptablesSnatRule,
×
903
                UpdateFunc: controller.enqueueUpdateIptablesSnatRule,
×
904
                DeleteFunc: controller.enqueueDelIptablesSnatRule,
×
905
        }); err != nil {
×
906
                util.LogFatalAndExit(err, "failed to add iptables snat rule event handler")
×
907
        }
×
908

909
        if _, err = ovnEipInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
910
                AddFunc:    controller.enqueueAddOvnEip,
×
911
                UpdateFunc: controller.enqueueUpdateOvnEip,
×
912
                DeleteFunc: controller.enqueueDelOvnEip,
×
913
        }); err != nil {
×
914
                util.LogFatalAndExit(err, "failed to add ovn eip event handler")
×
915
        }
×
916

917
        if _, err = ovnFipInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
918
                AddFunc:    controller.enqueueAddOvnFip,
×
919
                UpdateFunc: controller.enqueueUpdateOvnFip,
×
920
                DeleteFunc: controller.enqueueDelOvnFip,
×
921
        }); err != nil {
×
922
                util.LogFatalAndExit(err, "failed to add ovn fip event handler")
×
923
        }
×
924

925
        if _, err = ovnSnatRuleInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
926
                AddFunc:    controller.enqueueAddOvnSnatRule,
×
927
                UpdateFunc: controller.enqueueUpdateOvnSnatRule,
×
928
                DeleteFunc: controller.enqueueDelOvnSnatRule,
×
929
        }); err != nil {
×
930
                util.LogFatalAndExit(err, "failed to add ovn snat rule event handler")
×
931
        }
×
932

933
        if _, err = ovnDnatRuleInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
934
                AddFunc:    controller.enqueueAddOvnDnatRule,
×
935
                UpdateFunc: controller.enqueueUpdateOvnDnatRule,
×
936
                DeleteFunc: controller.enqueueDelOvnDnatRule,
×
937
        }); err != nil {
×
938
                util.LogFatalAndExit(err, "failed to add ovn dnat rule event handler")
×
939
        }
×
940

941
        if _, err = qosPolicyInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
942
                AddFunc:    controller.enqueueAddQoSPolicy,
×
943
                UpdateFunc: controller.enqueueUpdateQoSPolicy,
×
944
                DeleteFunc: controller.enqueueDelQoSPolicy,
×
945
        }); err != nil {
×
946
                util.LogFatalAndExit(err, "failed to add qos policy event handler")
×
947
        }
×
948

949
        if config.EnableLb {
×
950
                if _, err = switchLBRuleInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
951
                        AddFunc:    controller.enqueueAddSwitchLBRule,
×
952
                        UpdateFunc: controller.enqueueUpdateSwitchLBRule,
×
953
                        DeleteFunc: controller.enqueueDeleteSwitchLBRule,
×
954
                }); err != nil {
×
955
                        util.LogFatalAndExit(err, "failed to add switch lb rule event handler")
×
956
                }
×
957

958
                if _, err = vpcDNSInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
959
                        AddFunc:    controller.enqueueAddVpcDNS,
×
960
                        UpdateFunc: controller.enqueueUpdateVpcDNS,
×
961
                        DeleteFunc: controller.enqueueDeleteVPCDNS,
×
962
                }); err != nil {
×
963
                        util.LogFatalAndExit(err, "failed to add vpc dns event handler")
×
964
                }
×
965
        }
966

967
        if config.EnableNP {
×
968
                if _, err = npInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
969
                        AddFunc:    controller.enqueueAddNp,
×
970
                        UpdateFunc: controller.enqueueUpdateNp,
×
971
                        DeleteFunc: controller.enqueueDeleteNp,
×
972
                }); err != nil {
×
973
                        util.LogFatalAndExit(err, "failed to add network policy event handler")
×
974
                }
×
975
        }
976

977
        if config.EnableANP {
×
978
                if _, err = anpInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
979
                        AddFunc:    controller.enqueueAddAnp,
×
980
                        UpdateFunc: controller.enqueueUpdateAnp,
×
981
                        DeleteFunc: controller.enqueueDeleteAnp,
×
982
                }); err != nil {
×
983
                        util.LogFatalAndExit(err, "failed to add admin network policy event handler")
×
984
                }
×
985

986
                if _, err = banpInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
987
                        AddFunc:    controller.enqueueAddBanp,
×
988
                        UpdateFunc: controller.enqueueUpdateBanp,
×
989
                        DeleteFunc: controller.enqueueDeleteBanp,
×
990
                }); err != nil {
×
991
                        util.LogFatalAndExit(err, "failed to add baseline admin network policy event handler")
×
992
                }
×
993

994
                if _, err = cnpInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
995
                        AddFunc:    controller.enqueueAddCnp,
×
996
                        UpdateFunc: controller.enqueueUpdateCnp,
×
997
                        DeleteFunc: controller.enqueueDeleteCnp,
×
998
                }); err != nil {
×
999
                        util.LogFatalAndExit(err, "failed to add cluster network policy event handler")
×
1000
                }
×
1001

1002
                maxPriorityPerMap := util.CnpMaxPriority + 1
×
1003
                controller.anpPrioNameMap = make(map[int32]string, maxPriorityPerMap)
×
1004
                controller.anpNamePrioMap = make(map[string]int32, maxPriorityPerMap)
×
1005
                controller.bnpPrioNameMap = make(map[int32]string, maxPriorityPerMap)
×
1006
                controller.bnpNamePrioMap = make(map[string]int32, maxPriorityPerMap)
×
1007
        }
1008

1009
        if config.EnableDNSNameResolver {
×
1010
                if _, err = dnsNameResolverInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
1011
                        AddFunc:    controller.enqueueAddDNSNameResolver,
×
1012
                        UpdateFunc: controller.enqueueUpdateDNSNameResolver,
×
1013
                        DeleteFunc: controller.enqueueDeleteDNSNameResolver,
×
1014
                }); err != nil {
×
1015
                        util.LogFatalAndExit(err, "failed to add dns name resolver event handler")
×
1016
                }
×
1017
        }
1018

1019
        if config.EnableOVNIPSec {
×
1020
                if _, err = csrInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
×
1021
                        AddFunc:    controller.enqueueAddCsr,
×
1022
                        UpdateFunc: controller.enqueueUpdateCsr,
×
1023
                        // no need to add delete func for csr
×
1024
                }); err != nil {
×
1025
                        util.LogFatalAndExit(err, "failed to add csr event handler")
×
1026
                }
×
1027
        }
1028

1029
        controller.Run(ctx)
×
1030
}
1031

1032
// Run will set up the event handlers for types we are interested in, as well
1033
// as syncing informer caches and starting workers. It will block until stopCh
1034
// is closed, at which point it will shutdown the workqueue and wait for
1035
// workers to finish processing their current work items.
1036
func (c *Controller) Run(ctx context.Context) {
×
1037
        // The init process can only be placed here if the init process do really affect the normal process of controller, such as Nodes/Pods/Subnets...
×
1038
        // Otherwise, the init process should be placed after all workers have already started working
×
1039
        if err := c.OVNNbClient.SetLsDnatModDlDst(c.config.LsDnatModDlDst); err != nil {
×
1040
                util.LogFatalAndExit(err, "failed to set NB_Global option ls_dnat_mod_dl_dst")
×
1041
        }
×
1042

1043
        if err := c.OVNNbClient.SetUseCtInvMatch(); err != nil {
×
1044
                util.LogFatalAndExit(err, "failed to set NB_Global option use_ct_inv_match to false")
×
1045
        }
×
1046

1047
        if err := c.OVNNbClient.SetLsCtSkipDstLportIPs(c.config.LsCtSkipDstLportIPs); err != nil {
×
1048
                util.LogFatalAndExit(err, "failed to set NB_Global option ls_ct_skip_dst_lport_ips")
×
1049
        }
×
1050

1051
        if err := c.OVNNbClient.SetNodeLocalDNSIP(strings.Join(c.config.NodeLocalDNSIPs, ",")); err != nil {
×
1052
                util.LogFatalAndExit(err, "failed to set NB_Global option node_local_dns_ip")
×
1053
        }
×
1054

1055
        if err := c.OVNNbClient.SetSkipConntrackCidrs(c.config.SkipConntrackDstCidrs); err != nil {
×
1056
                util.LogFatalAndExit(err, "failed to set NB_Global option skip_conntrack_ipcidrs")
×
1057
        }
×
1058

1059
        if err := c.OVNNbClient.SetOVNIPSec(c.config.EnableOVNIPSec); err != nil {
×
1060
                util.LogFatalAndExit(err, "failed to set NB_Global ipsec")
×
1061
        }
×
1062

1063
        if err := c.InitOVN(); err != nil {
×
1064
                util.LogFatalAndExit(err, "failed to initialize ovn resources")
×
1065
        }
×
1066

1067
        // sync ip crd before initIPAM since ip crd will be used to restore vm and statefulset pod in initIPAM
1068
        if err := c.syncIPCR(); err != nil {
×
1069
                util.LogFatalAndExit(err, "failed to sync crd ips")
×
1070
        }
×
1071

1072
        if err := c.syncFinalizers(); err != nil {
×
1073
                util.LogFatalAndExit(err, "failed to initialize crd finalizers")
×
1074
        }
×
1075

1076
        if err := c.InitIPAM(); err != nil {
×
1077
                util.LogFatalAndExit(err, "failed to initialize ipam")
×
1078
        }
×
1079

1080
        if err := c.syncNodeRoutes(); err != nil {
×
1081
                util.LogFatalAndExit(err, "failed to initialize node routes")
×
1082
        }
×
1083

1084
        if err := c.syncSubnetCR(); err != nil {
×
1085
                util.LogFatalAndExit(err, "failed to sync crd subnets")
×
1086
        }
×
1087

1088
        if err := c.syncVlanCR(); err != nil {
×
1089
                util.LogFatalAndExit(err, "failed to sync crd vlans")
×
1090
        }
×
1091

1092
        if c.config.EnableOVNIPSec && !c.config.CertManagerIPSecCert {
×
1093
                if err := c.InitDefaultOVNIPsecCA(); err != nil {
×
1094
                        util.LogFatalAndExit(err, "failed to init ovn ipsec CA")
×
1095
                }
×
1096
        }
1097

1098
        // start workers to do all the network operations
1099
        c.startWorkers(ctx)
×
1100

×
1101
        c.initResourceOnce()
×
1102
        <-ctx.Done()
×
1103
        klog.Info("Shutting down workers")
×
1104

×
1105
        c.OVNNbClient.Close()
×
1106
        c.OVNSbClient.Close()
×
1107
}
1108

1109
func (c *Controller) dbStatus() {
×
1110
        const maxFailures = 5
×
1111

×
1112
        done := make(chan error, 2)
×
1113
        go func() {
×
1114
                done <- c.OVNNbClient.Echo(context.Background())
×
1115
        }()
×
1116
        go func() {
×
1117
                done <- c.OVNSbClient.Echo(context.Background())
×
1118
        }()
×
1119

1120
        resultsReceived := 0
×
1121
        timeout := time.After(time.Duration(c.config.OvnTimeout) * time.Second)
×
1122

×
1123
        for resultsReceived < 2 {
×
1124
                select {
×
1125
                case err := <-done:
×
1126
                        resultsReceived++
×
1127
                        if err != nil {
×
1128
                                c.dbFailureCount++
×
1129
                                klog.Errorf("OVN database echo failed (%d/%d): %v", c.dbFailureCount, maxFailures, err)
×
1130
                                if c.dbFailureCount >= maxFailures {
×
1131
                                        util.LogFatalAndExit(err, "OVN database connection failed after %d attempts", maxFailures)
×
1132
                                }
×
1133
                                return
×
1134
                        }
1135
                case <-timeout:
×
1136
                        c.dbFailureCount++
×
1137
                        klog.Errorf("OVN database echo timeout (%d/%d) after %ds", c.dbFailureCount, maxFailures, c.config.OvnTimeout)
×
1138
                        if c.dbFailureCount >= maxFailures {
×
1139
                                util.LogFatalAndExit(nil, "OVN database connection timeout after %d attempts", maxFailures)
×
1140
                        }
×
1141
                        return
×
1142
                }
1143
        }
1144

1145
        if c.dbFailureCount > 0 {
×
1146
                klog.Infof("OVN database connection recovered after %d failures", c.dbFailureCount)
×
1147
                c.dbFailureCount = 0
×
1148
        }
×
1149
}
1150

1151
func (c *Controller) shutdown() {
×
1152
        utilruntime.HandleCrash()
×
1153

×
1154
        c.addOrUpdatePodQueue.ShutDown()
×
1155
        c.deletePodQueue.ShutDown()
×
1156
        c.updatePodSecurityQueue.ShutDown()
×
1157

×
1158
        c.addNamespaceQueue.ShutDown()
×
1159

×
1160
        c.addOrUpdateSubnetQueue.ShutDown()
×
1161
        c.deleteSubnetQueue.ShutDown()
×
1162
        c.updateSubnetStatusQueue.ShutDown()
×
1163
        c.syncVirtualPortsQueue.ShutDown()
×
1164

×
1165
        c.addOrUpdateIPPoolQueue.ShutDown()
×
1166
        c.updateIPPoolStatusQueue.ShutDown()
×
1167
        c.deleteIPPoolQueue.ShutDown()
×
1168

×
1169
        c.addNodeQueue.ShutDown()
×
1170
        c.updateNodeQueue.ShutDown()
×
1171
        c.deleteNodeQueue.ShutDown()
×
1172

×
1173
        c.addServiceQueue.ShutDown()
×
1174
        c.deleteServiceQueue.ShutDown()
×
1175
        c.updateServiceQueue.ShutDown()
×
1176
        c.addOrUpdateEndpointSliceQueue.ShutDown()
×
1177

×
1178
        c.addVlanQueue.ShutDown()
×
1179
        c.delVlanQueue.ShutDown()
×
1180
        c.updateVlanQueue.ShutDown()
×
1181

×
1182
        c.addOrUpdateVpcQueue.ShutDown()
×
1183
        c.updateVpcStatusQueue.ShutDown()
×
1184
        c.delVpcQueue.ShutDown()
×
1185

×
1186
        c.addOrUpdateVpcNatGatewayQueue.ShutDown()
×
1187
        c.initVpcNatGatewayQueue.ShutDown()
×
1188
        c.delVpcNatGatewayQueue.ShutDown()
×
1189
        c.updateVpcEipQueue.ShutDown()
×
1190
        c.updateVpcFloatingIPQueue.ShutDown()
×
1191
        c.updateVpcDnatQueue.ShutDown()
×
1192
        c.updateVpcSnatQueue.ShutDown()
×
1193
        c.updateVpcSubnetQueue.ShutDown()
×
1194

×
1195
        c.addOrUpdateVpcEgressGatewayQueue.ShutDown()
×
1196
        c.delVpcEgressGatewayQueue.ShutDown()
×
1197

×
1198
        if c.config.EnableLb {
×
1199
                c.addSwitchLBRuleQueue.ShutDown()
×
1200
                c.delSwitchLBRuleQueue.ShutDown()
×
1201
                c.updateSwitchLBRuleQueue.ShutDown()
×
1202

×
1203
                c.addOrUpdateVpcDNSQueue.ShutDown()
×
1204
                c.delVpcDNSQueue.ShutDown()
×
1205
        }
×
1206

1207
        c.addIPQueue.ShutDown()
×
1208
        c.updateIPQueue.ShutDown()
×
1209
        c.delIPQueue.ShutDown()
×
1210

×
1211
        c.addVirtualIPQueue.ShutDown()
×
1212
        c.updateVirtualIPQueue.ShutDown()
×
1213
        c.updateVirtualParentsQueue.ShutDown()
×
1214
        c.delVirtualIPQueue.ShutDown()
×
1215

×
1216
        c.addIptablesEipQueue.ShutDown()
×
1217
        c.updateIptablesEipQueue.ShutDown()
×
1218
        c.resetIptablesEipQueue.ShutDown()
×
1219
        c.delIptablesEipQueue.ShutDown()
×
1220

×
1221
        c.addIptablesFipQueue.ShutDown()
×
1222
        c.updateIptablesFipQueue.ShutDown()
×
1223
        c.delIptablesFipQueue.ShutDown()
×
1224

×
1225
        c.addIptablesDnatRuleQueue.ShutDown()
×
1226
        c.updateIptablesDnatRuleQueue.ShutDown()
×
1227
        c.delIptablesDnatRuleQueue.ShutDown()
×
1228

×
1229
        c.addIptablesSnatRuleQueue.ShutDown()
×
1230
        c.updateIptablesSnatRuleQueue.ShutDown()
×
1231
        c.delIptablesSnatRuleQueue.ShutDown()
×
1232

×
1233
        c.addQoSPolicyQueue.ShutDown()
×
1234
        c.updateQoSPolicyQueue.ShutDown()
×
1235
        c.delQoSPolicyQueue.ShutDown()
×
1236

×
1237
        c.addOvnEipQueue.ShutDown()
×
1238
        c.updateOvnEipQueue.ShutDown()
×
1239
        c.resetOvnEipQueue.ShutDown()
×
1240
        c.delOvnEipQueue.ShutDown()
×
1241

×
1242
        c.addOvnFipQueue.ShutDown()
×
1243
        c.updateOvnFipQueue.ShutDown()
×
1244
        c.delOvnFipQueue.ShutDown()
×
1245

×
1246
        c.addOvnSnatRuleQueue.ShutDown()
×
1247
        c.updateOvnSnatRuleQueue.ShutDown()
×
1248
        c.delOvnSnatRuleQueue.ShutDown()
×
1249

×
1250
        c.addOvnDnatRuleQueue.ShutDown()
×
1251
        c.updateOvnDnatRuleQueue.ShutDown()
×
1252
        c.delOvnDnatRuleQueue.ShutDown()
×
1253

×
1254
        if c.config.EnableNP {
×
1255
                c.updateNpQueue.ShutDown()
×
1256
                c.deleteNpQueue.ShutDown()
×
1257
        }
×
1258
        if c.config.EnableANP {
×
1259
                c.addAnpQueue.ShutDown()
×
1260
                c.updateAnpQueue.ShutDown()
×
1261
                c.deleteAnpQueue.ShutDown()
×
1262

×
1263
                c.addBanpQueue.ShutDown()
×
1264
                c.updateBanpQueue.ShutDown()
×
1265
                c.deleteBanpQueue.ShutDown()
×
1266

×
1267
                c.addCnpQueue.ShutDown()
×
1268
                c.updateCnpQueue.ShutDown()
×
1269
                c.deleteCnpQueue.ShutDown()
×
1270
        }
×
1271

1272
        if c.config.EnableDNSNameResolver {
×
1273
                c.addOrUpdateDNSNameResolverQueue.ShutDown()
×
1274
                c.deleteDNSNameResolverQueue.ShutDown()
×
1275
        }
×
1276

1277
        c.addOrUpdateSgQueue.ShutDown()
×
1278
        c.delSgQueue.ShutDown()
×
1279
        c.syncSgPortsQueue.ShutDown()
×
1280

×
1281
        c.addOrUpdateCsrQueue.ShutDown()
×
1282

×
1283
        if c.config.EnableLiveMigrationOptimize {
×
1284
                c.addOrUpdateVMIMigrationQueue.ShutDown()
×
1285
        }
×
1286
}
1287

1288
func (c *Controller) startWorkers(ctx context.Context) {
×
1289
        klog.Info("Starting workers")
×
1290

×
1291
        go wait.Until(runWorker("add/update vpc", c.addOrUpdateVpcQueue, c.handleAddOrUpdateVpc), time.Second, ctx.Done())
×
1292
        go wait.Until(runWorker("delete vpc", c.delVpcQueue, c.handleDelVpc), time.Second, ctx.Done())
×
1293
        go wait.Until(runWorker("update status of vpc", c.updateVpcStatusQueue, c.handleUpdateVpcStatus), time.Second, ctx.Done())
×
1294

×
1295
        go wait.Until(runWorker("add/update vpc nat gateway", c.addOrUpdateVpcNatGatewayQueue, c.handleAddOrUpdateVpcNatGw), time.Second, ctx.Done())
×
1296
        go wait.Until(runWorker("init vpc nat gateway", c.initVpcNatGatewayQueue, c.handleInitVpcNatGw), time.Second, ctx.Done())
×
1297
        go wait.Until(runWorker("delete vpc nat gateway", c.delVpcNatGatewayQueue, c.handleDelVpcNatGw), time.Second, ctx.Done())
×
1298
        go wait.Until(runWorker("add/update vpc egress gateway", c.addOrUpdateVpcEgressGatewayQueue, c.handleAddOrUpdateVpcEgressGateway), time.Second, ctx.Done())
×
1299
        go wait.Until(runWorker("delete vpc egress gateway", c.delVpcEgressGatewayQueue, c.handleDelVpcEgressGateway), time.Second, ctx.Done())
×
1300
        go wait.Until(runWorker("update fip for vpc nat gateway", c.updateVpcFloatingIPQueue, c.handleUpdateVpcFloatingIP), time.Second, ctx.Done())
×
1301
        go wait.Until(runWorker("update eip for vpc nat gateway", c.updateVpcEipQueue, c.handleUpdateVpcEip), time.Second, ctx.Done())
×
1302
        go wait.Until(runWorker("update dnat for vpc nat gateway", c.updateVpcDnatQueue, c.handleUpdateVpcDnat), time.Second, ctx.Done())
×
1303
        go wait.Until(runWorker("update snat for vpc nat gateway", c.updateVpcSnatQueue, c.handleUpdateVpcSnat), time.Second, ctx.Done())
×
1304
        go wait.Until(runWorker("update subnet route for vpc nat gateway", c.updateVpcSubnetQueue, c.handleUpdateNatGwSubnetRoute), time.Second, ctx.Done())
×
1305
        go wait.Until(runWorker("add/update csr", c.addOrUpdateCsrQueue, c.handleAddOrUpdateCsr), time.Second, ctx.Done())
×
1306
        // add default and join subnet and wait them ready
×
1307
        for range c.config.WorkerNum {
×
1308
                go wait.Until(runWorker("add/update subnet", c.addOrUpdateSubnetQueue, c.handleAddOrUpdateSubnet), time.Second, ctx.Done())
×
1309
        }
×
1310
        go wait.Until(runWorker("add/update ippool", c.addOrUpdateIPPoolQueue, c.handleAddOrUpdateIPPool), time.Second, ctx.Done())
×
1311
        go wait.Until(runWorker("add vlan", c.addVlanQueue, c.handleAddVlan), time.Second, ctx.Done())
×
1312
        go wait.Until(runWorker("add namespace", c.addNamespaceQueue, c.handleAddNamespace), time.Second, ctx.Done())
×
1313
        err := wait.PollUntilContextCancel(ctx, 3*time.Second, true, func(_ context.Context) (done bool, err error) {
×
1314
                subnets := []string{c.config.DefaultLogicalSwitch, c.config.NodeSwitch}
×
1315
                klog.Infof("wait for subnets %v ready", subnets)
×
1316

×
1317
                return c.allSubnetReady(subnets...)
×
1318
        })
×
1319
        if err != nil {
×
1320
                klog.Fatalf("wait default and join subnet ready, error: %v", err)
×
1321
        }
×
1322

1323
        go wait.Until(runWorker("add/update security group", c.addOrUpdateSgQueue, func(key string) error { return c.handleAddOrUpdateSg(key, false) }), time.Second, ctx.Done())
×
1324
        go wait.Until(runWorker("delete security group", c.delSgQueue, c.handleDeleteSg), time.Second, ctx.Done())
×
1325
        go wait.Until(runWorker("ports for security group", c.syncSgPortsQueue, c.syncSgLogicalPort), time.Second, ctx.Done())
×
1326

×
1327
        // run node worker before handle any pods
×
1328
        for range c.config.WorkerNum {
×
1329
                go wait.Until(runWorker("add node", c.addNodeQueue, c.handleAddNode), time.Second, ctx.Done())
×
1330
                go wait.Until(runWorker("update node", c.updateNodeQueue, c.handleUpdateNode), time.Second, ctx.Done())
×
1331
                go wait.Until(runWorker("delete node", c.deleteNodeQueue, c.handleDeleteNode), time.Second, ctx.Done())
×
1332
        }
×
1333
        for {
×
1334
                ready := true
×
1335
                time.Sleep(3 * time.Second)
×
1336
                nodes, err := c.nodesLister.List(labels.Everything())
×
1337
                if err != nil {
×
1338
                        util.LogFatalAndExit(err, "failed to list nodes")
×
1339
                }
×
1340
                for _, node := range nodes {
×
1341
                        if node.Annotations[util.AllocatedAnnotation] != "true" {
×
1342
                                klog.Infof("wait node %s annotation ready", node.Name)
×
1343
                                ready = false
×
1344
                                break
×
1345
                        }
1346
                }
1347
                if ready {
×
1348
                        break
×
1349
                }
1350
        }
1351

1352
        if c.config.EnableLb {
×
1353
                go wait.Until(runWorker("add service", c.addServiceQueue, c.handleAddService), time.Second, ctx.Done())
×
1354
                // run in a single worker to avoid delete the last vip, which will lead ovn to delete the loadbalancer
×
1355
                go wait.Until(runWorker("delete service", c.deleteServiceQueue, c.handleDeleteService), time.Second, ctx.Done())
×
1356

×
1357
                go wait.Until(runWorker("add/update switch lb rule", c.addSwitchLBRuleQueue, c.handleAddOrUpdateSwitchLBRule), time.Second, ctx.Done())
×
1358
                go wait.Until(runWorker("delete switch lb rule", c.delSwitchLBRuleQueue, c.handleDelSwitchLBRule), time.Second, ctx.Done())
×
1359
                go wait.Until(runWorker("delete switch lb rule", c.updateSwitchLBRuleQueue, c.handleUpdateSwitchLBRule), time.Second, ctx.Done())
×
1360

×
1361
                go wait.Until(runWorker("add/update vpc dns", c.addOrUpdateVpcDNSQueue, c.handleAddOrUpdateVPCDNS), time.Second, ctx.Done())
×
1362
                go wait.Until(runWorker("delete vpc dns", c.delVpcDNSQueue, c.handleDelVpcDNS), time.Second, ctx.Done())
×
1363
                go wait.Until(func() {
×
1364
                        c.resyncVpcDNSConfig()
×
1365
                }, 5*time.Second, ctx.Done())
×
1366
        }
1367

1368
        for range c.config.WorkerNum {
×
1369
                go wait.Until(runWorker("delete pod", c.deletePodQueue, c.handleDeletePod), time.Second, ctx.Done())
×
1370
                go wait.Until(runWorker("add/update pod", c.addOrUpdatePodQueue, c.handleAddOrUpdatePod), time.Second, ctx.Done())
×
1371
                go wait.Until(runWorker("update pod security", c.updatePodSecurityQueue, c.handleUpdatePodSecurity), time.Second, ctx.Done())
×
1372

×
1373
                go wait.Until(runWorker("delete subnet", c.deleteSubnetQueue, c.handleDeleteSubnet), time.Second, ctx.Done())
×
1374
                go wait.Until(runWorker("delete ippool", c.deleteIPPoolQueue, c.handleDeleteIPPool), time.Second, ctx.Done())
×
1375
                go wait.Until(runWorker("update status of subnet", c.updateSubnetStatusQueue, c.handleUpdateSubnetStatus), time.Second, ctx.Done())
×
1376
                go wait.Until(runWorker("update status of ippool", c.updateIPPoolStatusQueue, c.handleUpdateIPPoolStatus), time.Second, ctx.Done())
×
1377
                go wait.Until(runWorker("virtual port for subnet", c.syncVirtualPortsQueue, c.syncVirtualPort), time.Second, ctx.Done())
×
1378

×
1379
                if c.config.EnableLb {
×
1380
                        go wait.Until(runWorker("update service", c.updateServiceQueue, c.handleUpdateService), time.Second, ctx.Done())
×
1381
                        go wait.Until(runWorker("add/update endpoint slice", c.addOrUpdateEndpointSliceQueue, c.handleUpdateEndpointSlice), time.Second, ctx.Done())
×
1382
                }
×
1383

1384
                if c.config.EnableNP {
×
1385
                        go wait.Until(runWorker("update network policy", c.updateNpQueue, c.handleUpdateNp), time.Second, ctx.Done())
×
1386
                        go wait.Until(runWorker("delete network policy", c.deleteNpQueue, c.handleDeleteNp), time.Second, ctx.Done())
×
1387
                }
×
1388

1389
                go wait.Until(runWorker("delete vlan", c.delVlanQueue, c.handleDelVlan), time.Second, ctx.Done())
×
1390
                go wait.Until(runWorker("update vlan", c.updateVlanQueue, c.handleUpdateVlan), time.Second, ctx.Done())
×
1391
        }
1392

1393
        if c.config.EnableEipSnat {
×
1394
                go wait.Until(func() {
×
1395
                        // init l3 about the default vpc external lrp binding to the gw chassis
×
1396
                        c.resyncExternalGateway()
×
1397
                }, time.Second, ctx.Done())
×
1398

1399
                // maintain l3 ha about the vpc external lrp binding to the gw chassis
1400
                c.OVNNbClient.MonitorBFD()
×
1401
        }
1402
        // TODO: we should merge these two vpc nat config into one config and resync them together
1403
        go wait.Until(func() {
×
1404
                c.resyncVpcNatGwConfig()
×
1405
        }, time.Second, ctx.Done())
×
1406

1407
        go wait.Until(func() {
×
1408
                c.resyncVpcNatConfig()
×
1409
        }, time.Second, ctx.Done())
×
1410

1411
        if c.config.GCInterval != 0 {
×
1412
                go wait.Until(func() {
×
1413
                        if err := c.markAndCleanLSP(); err != nil {
×
1414
                                klog.Errorf("gc lsp error: %v", err)
×
1415
                        }
×
1416
                }, time.Duration(c.config.GCInterval)*time.Second, ctx.Done())
1417
        }
1418

1419
        go wait.Until(func() {
×
1420
                if err := c.inspectPod(); err != nil {
×
1421
                        klog.Errorf("inspection error: %v", err)
×
1422
                }
×
1423
        }, time.Duration(c.config.InspectInterval)*time.Second, ctx.Done())
1424

1425
        if c.config.EnableExternalVpc {
×
1426
                go wait.Until(func() {
×
1427
                        c.syncExternalVpc()
×
1428
                }, 5*time.Second, ctx.Done())
×
1429
        }
1430

1431
        go wait.Until(c.resyncProviderNetworkStatus, 30*time.Second, ctx.Done())
×
1432
        go wait.Until(c.exportSubnetMetrics, 30*time.Second, ctx.Done())
×
1433
        go wait.Until(c.checkSubnetGateway, 5*time.Second, ctx.Done())
×
1434
        go wait.Until(c.syncDistributedSubnetRoutes, 5*time.Second, ctx.Done())
×
1435

×
1436
        go wait.Until(runWorker("add ovn eip", c.addOvnEipQueue, c.handleAddOvnEip), time.Second, ctx.Done())
×
1437
        go wait.Until(runWorker("update ovn eip", c.updateOvnEipQueue, c.handleUpdateOvnEip), time.Second, ctx.Done())
×
1438
        go wait.Until(runWorker("reset ovn eip", c.resetOvnEipQueue, c.handleResetOvnEip), time.Second, ctx.Done())
×
1439
        go wait.Until(runWorker("delete ovn eip", c.delOvnEipQueue, c.handleDelOvnEip), time.Second, ctx.Done())
×
1440

×
1441
        go wait.Until(runWorker("add ovn fip", c.addOvnFipQueue, c.handleAddOvnFip), time.Second, ctx.Done())
×
1442
        go wait.Until(runWorker("update ovn fip", c.updateOvnFipQueue, c.handleUpdateOvnFip), time.Second, ctx.Done())
×
1443
        go wait.Until(runWorker("delete ovn fip", c.delOvnFipQueue, c.handleDelOvnFip), time.Second, ctx.Done())
×
1444

×
1445
        go wait.Until(runWorker("add ovn snat rule", c.addOvnSnatRuleQueue, c.handleAddOvnSnatRule), time.Second, ctx.Done())
×
1446
        go wait.Until(runWorker("update ovn snat rule", c.updateOvnSnatRuleQueue, c.handleUpdateOvnSnatRule), time.Second, ctx.Done())
×
1447
        go wait.Until(runWorker("delete ovn snat rule", c.delOvnSnatRuleQueue, c.handleDelOvnSnatRule), time.Second, ctx.Done())
×
1448

×
1449
        go wait.Until(runWorker("add ovn dnat", c.addOvnDnatRuleQueue, c.handleAddOvnDnatRule), time.Second, ctx.Done())
×
1450
        go wait.Until(runWorker("update ovn dnat", c.updateOvnDnatRuleQueue, c.handleUpdateOvnDnatRule), time.Second, ctx.Done())
×
1451
        go wait.Until(runWorker("delete ovn dnat", c.delOvnDnatRuleQueue, c.handleDelOvnDnatRule), time.Second, ctx.Done())
×
1452

×
1453
        go wait.Until(c.CheckNodePortGroup, time.Duration(c.config.NodePgProbeTime)*time.Minute, ctx.Done())
×
1454

×
1455
        go wait.Until(runWorker("add ip", c.addIPQueue, c.handleAddReservedIP), time.Second, ctx.Done())
×
1456
        go wait.Until(runWorker("update ip", c.updateIPQueue, c.handleUpdateIP), time.Second, ctx.Done())
×
1457
        go wait.Until(runWorker("delete ip", c.delIPQueue, c.handleDelIP), time.Second, ctx.Done())
×
1458

×
1459
        go wait.Until(runWorker("add vip", c.addVirtualIPQueue, c.handleAddVirtualIP), time.Second, ctx.Done())
×
1460
        go wait.Until(runWorker("update vip", c.updateVirtualIPQueue, c.handleUpdateVirtualIP), time.Second, ctx.Done())
×
1461
        go wait.Until(runWorker("update virtual parent for vip", c.updateVirtualParentsQueue, c.handleUpdateVirtualParents), time.Second, ctx.Done())
×
1462
        go wait.Until(runWorker("delete vip", c.delVirtualIPQueue, c.handleDelVirtualIP), time.Second, ctx.Done())
×
1463

×
1464
        go wait.Until(runWorker("add iptables eip", c.addIptablesEipQueue, c.handleAddIptablesEip), time.Second, ctx.Done())
×
1465
        go wait.Until(runWorker("update iptables eip", c.updateIptablesEipQueue, c.handleUpdateIptablesEip), time.Second, ctx.Done())
×
1466
        go wait.Until(runWorker("reset iptables eip", c.resetIptablesEipQueue, c.handleResetIptablesEip), time.Second, ctx.Done())
×
1467
        go wait.Until(runWorker("delete iptables eip", c.delIptablesEipQueue, c.handleDelIptablesEip), time.Second, ctx.Done())
×
1468

×
1469
        go wait.Until(runWorker("add iptables fip", c.addIptablesFipQueue, c.handleAddIptablesFip), time.Second, ctx.Done())
×
1470
        go wait.Until(runWorker("update iptables fip", c.updateIptablesFipQueue, c.handleUpdateIptablesFip), time.Second, ctx.Done())
×
1471
        go wait.Until(runWorker("delete iptables fip", c.delIptablesFipQueue, c.handleDelIptablesFip), time.Second, ctx.Done())
×
1472

×
1473
        go wait.Until(runWorker("add iptables dnat rule", c.addIptablesDnatRuleQueue, c.handleAddIptablesDnatRule), time.Second, ctx.Done())
×
1474
        go wait.Until(runWorker("update iptables dnat rule", c.updateIptablesDnatRuleQueue, c.handleUpdateIptablesDnatRule), time.Second, ctx.Done())
×
1475
        go wait.Until(runWorker("delete iptables dnat rule", c.delIptablesDnatRuleQueue, c.handleDelIptablesDnatRule), time.Second, ctx.Done())
×
1476

×
1477
        go wait.Until(runWorker("add iptables snat rule", c.addIptablesSnatRuleQueue, c.handleAddIptablesSnatRule), time.Second, ctx.Done())
×
1478
        go wait.Until(runWorker("update iptables snat rule", c.updateIptablesSnatRuleQueue, c.handleUpdateIptablesSnatRule), time.Second, ctx.Done())
×
1479
        go wait.Until(runWorker("delete iptables snat rule", c.delIptablesSnatRuleQueue, c.handleDelIptablesSnatRule), time.Second, ctx.Done())
×
1480

×
1481
        go wait.Until(runWorker("add qos policy", c.addQoSPolicyQueue, c.handleAddQoSPolicy), time.Second, ctx.Done())
×
1482
        go wait.Until(runWorker("update qos policy", c.updateQoSPolicyQueue, c.handleUpdateQoSPolicy), time.Second, ctx.Done())
×
1483
        go wait.Until(runWorker("delete qos policy", c.delQoSPolicyQueue, c.handleDelQoSPolicy), time.Second, ctx.Done())
×
1484

×
1485
        if c.config.EnableANP {
×
1486
                go wait.Until(runWorker("add admin network policy", c.addAnpQueue, c.handleAddAnp), time.Second, ctx.Done())
×
1487
                go wait.Until(runWorker("update admin network policy", c.updateAnpQueue, c.handleUpdateAnp), time.Second, ctx.Done())
×
1488
                go wait.Until(runWorker("delete admin network policy", c.deleteAnpQueue, c.handleDeleteAnp), time.Second, ctx.Done())
×
1489

×
1490
                go wait.Until(runWorker("add base admin network policy", c.addBanpQueue, c.handleAddBanp), time.Second, ctx.Done())
×
1491
                go wait.Until(runWorker("update base admin network policy", c.updateBanpQueue, c.handleUpdateBanp), time.Second, ctx.Done())
×
1492
                go wait.Until(runWorker("delete base admin network policy", c.deleteBanpQueue, c.handleDeleteBanp), time.Second, ctx.Done())
×
1493

×
1494
                go wait.Until(runWorker("add cluster network policy", c.addCnpQueue, c.handleAddCnp), time.Second, ctx.Done())
×
1495
                go wait.Until(runWorker("update cluster network policy", c.updateCnpQueue, c.handleUpdateCnp), time.Second, ctx.Done())
×
1496
                go wait.Until(runWorker("delete cluster network policy", c.deleteCnpQueue, c.handleDeleteCnp), time.Second, ctx.Done())
×
1497
        }
×
1498

1499
        if c.config.EnableDNSNameResolver {
×
1500
                go wait.Until(runWorker("add or update dns name resolver", c.addOrUpdateDNSNameResolverQueue, c.handleAddOrUpdateDNSNameResolver), time.Second, ctx.Done())
×
1501
                go wait.Until(runWorker("delete dns name resolver", c.deleteDNSNameResolverQueue, c.handleDeleteDNSNameResolver), time.Second, ctx.Done())
×
1502
        }
×
1503

1504
        if c.config.EnableLiveMigrationOptimize {
×
1505
                go wait.Until(runWorker("add/update vmiMigration ", c.addOrUpdateVMIMigrationQueue, c.handleAddOrUpdateVMIMigration), 50*time.Millisecond, ctx.Done())
×
1506
        }
×
1507

1508
        go wait.Until(runWorker("delete vm", c.deleteVMQueue, c.handleDeleteVM), time.Second, ctx.Done())
×
1509

×
1510
        go wait.Until(c.dbStatus, 15*time.Second, ctx.Done())
×
1511
}
1512

1513
func (c *Controller) allSubnetReady(subnets ...string) (bool, error) {
1✔
1514
        for _, lsName := range subnets {
2✔
1515
                exist, err := c.OVNNbClient.LogicalSwitchExists(lsName)
1✔
1516
                if err != nil {
1✔
1517
                        klog.Error(err)
×
1518
                        return false, fmt.Errorf("check logical switch %s exist: %w", lsName, err)
×
1519
                }
×
1520

1521
                if !exist {
2✔
1522
                        return false, nil
1✔
1523
                }
1✔
1524
        }
1525

1526
        return true, nil
1✔
1527
}
1528

1529
func (c *Controller) initResourceOnce() {
×
1530
        c.registerSubnetMetrics()
×
1531

×
1532
        if err := c.initNodeChassis(); err != nil {
×
1533
                util.LogFatalAndExit(err, "failed to initialize node chassis")
×
1534
        }
×
1535

1536
        if err := c.initDefaultDenyAllSecurityGroup(); err != nil {
×
1537
                util.LogFatalAndExit(err, "failed to initialize 'deny_all' security group")
×
1538
        }
×
1539
        if err := c.syncSecurityGroup(); err != nil {
×
1540
                util.LogFatalAndExit(err, "failed to sync security group")
×
1541
        }
×
1542

1543
        if err := c.syncVpcNatGatewayCR(); err != nil {
×
1544
                util.LogFatalAndExit(err, "failed to sync crd vpc nat gateways")
×
1545
        }
×
1546

1547
        if err := c.initVpcNatGw(); err != nil {
×
1548
                util.LogFatalAndExit(err, "failed to initialize vpc nat gateways")
×
1549
        }
×
1550
        if c.config.EnableLb {
×
1551
                if err := c.initVpcDNSConfig(); err != nil {
×
1552
                        util.LogFatalAndExit(err, "failed to initialize vpc-dns")
×
1553
                }
×
1554
        }
1555

1556
        // remove resources in ovndb that not exist any more in kubernetes resources
1557
        // process gc at last in case of affecting other init process
1558
        if err := c.gc(); err != nil {
×
1559
                util.LogFatalAndExit(err, "failed to run gc")
×
1560
        }
×
1561
}
1562

1563
func processNextWorkItem[T comparable](action string, queue workqueue.TypedRateLimitingInterface[T], handler func(T) error, getItemKey func(any) string) bool {
×
1564
        item, shutdown := queue.Get()
×
1565
        if shutdown {
×
1566
                return false
×
1567
        }
×
1568

1569
        err := func(item T) error {
×
1570
                defer queue.Done(item)
×
1571
                if err := handler(item); err != nil {
×
1572
                        queue.AddRateLimited(item)
×
1573
                        return fmt.Errorf("error syncing %s %q: %w, requeuing", action, getItemKey(item), err)
×
1574
                }
×
1575
                queue.Forget(item)
×
1576
                return nil
×
1577
        }(item)
1578
        if err != nil {
×
1579
                utilruntime.HandleError(err)
×
1580
                return true
×
1581
        }
×
1582
        return true
×
1583
}
1584

1585
func getWorkItemKey(obj any) string {
×
1586
        switch v := obj.(type) {
×
1587
        case string:
×
1588
                return v
×
1589
        case *vpcService:
×
1590
                return cache.MetaObjectToName(obj.(*vpcService).Svc).String()
×
1591
        case *AdminNetworkPolicyChangedDelta:
×
1592
                return v.key
×
1593
        case *SlrInfo:
×
1594
                return v.Name
×
1595
        default:
×
1596
                key, err := cache.MetaNamespaceKeyFunc(obj)
×
1597
                if err != nil {
×
1598
                        utilruntime.HandleError(err)
×
1599
                        return ""
×
1600
                }
×
1601
                return key
×
1602
        }
1603
}
1604

1605
func runWorker[T comparable](action string, queue workqueue.TypedRateLimitingInterface[T], handler func(T) error) func() {
×
1606
        return func() {
×
1607
                for processNextWorkItem(action, queue, handler, getWorkItemKey) {
×
1608
                }
×
1609
        }
1610
}
1611

1612
// apiResourceExists checks if all specified kinds exist in the given group version.
1613
// It returns true if all kinds are found, false otherwise.
1614
// Parameters:
1615
// - discoveryClient: The discovery client to use for querying API resources.
1616
// - gv: The group version string (e.g., "apps/v1").
1617
// - kinds: A variadic list of kind names to check for existence (e.g., "Deployment", "StatefulSet").
1618
func apiResourceExists(discoveryClient discovery.DiscoveryInterface, gv string, kinds ...string) (bool, error) {
×
1619
        apiResourceLists, err := discoveryClient.ServerResourcesForGroupVersion(gv)
×
1620
        if err != nil {
×
1621
                if k8serrors.IsNotFound(err) {
×
1622
                        return false, nil
×
1623
                }
×
1624
                return false, fmt.Errorf("failed to discover api resources for %s: %w", gv, err)
×
1625
        }
1626

1627
        existingKinds := set.New[string]()
×
1628
        for _, apiResource := range apiResourceLists.APIResources {
×
1629
                existingKinds.Insert(apiResource.Kind)
×
1630
        }
×
1631

1632
        return existingKinds.HasAll(kinds...), nil
×
1633
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc