@@ -85,7 +85,6 @@ func (c *Controller) handleUpdateEndpointSlice(key string) error {
8585 svc := cachedService .DeepCopy ()
8686
8787 var (
88- pods []* v1.Pod
8988 lbVips []string
9089 vip , vpcName , subnetName string
9190 ok bool
@@ -123,11 +122,7 @@ func (c *Controller) handleUpdateEndpointSlice(key string) error {
123122 }
124123 }
125124
126- if pods , err = c .podsLister .Pods (namespace ).List (labels .Set (svc .Spec .Selector ).AsSelector ()); err != nil {
127- klog .Errorf ("failed to get pods for service %s in namespace %s: %v" , name , namespace , err )
128- return err
129- }
130- vpcName , subnetName = c .getVpcSubnetName (pods , endpointSlices , svc )
125+ vpcName , subnetName = c .getVpcSubnetName (endpointSlices , svc )
131126
132127 var (
133128 vpc * kubeovnv1.Vpc
@@ -241,40 +236,55 @@ func (c *Controller) handleUpdateEndpointSlice(key string) error {
241236 return nil
242237}
243238
244- func (c * Controller ) getVpcSubnetName (pods []* v1.Pod , endpointSlices []* discoveryv1.EndpointSlice , service * v1.Service ) (string , string ) {
245- var (
246- vpcName string
247- subnetName string
248- )
249-
250- for _ , pod := range pods {
251- if len (pod .Annotations ) == 0 {
252- continue
239+ func (c * Controller ) getVpcSubnetName (endpointSlices []* discoveryv1.EndpointSlice , service * v1.Service ) (vpcName , subnetName string ) {
240+ // Let the user self-determine what VPC and subnet to use
241+ if service .Annotations != nil {
242+ if vpc := service .Annotations [util .LogicalRouterAnnotation ]; vpc != "" {
243+ vpcName = vpc
253244 }
254- if subnetName = = "" {
255- subnetName = pod . Annotations [ util . LogicalSwitchAnnotation ]
245+ if subnet := service . Annotations [ util . LogicalSwitchAnnotation ]; subnet ! = "" {
246+ subnetName = subnet
256247 }
257248
258- LOOP:
259- for _ , endpointSlice := range endpointSlices {
260- for _ , endpoint := range endpointSlice .Endpoints {
261- for _ , addr := range endpoint .Addresses {
262- for _ , podIP := range pod .Status .PodIPs {
263- if addr == podIP .IP {
264- if vpcName == "" {
265- vpcName = pod .Annotations [util .LogicalRouterAnnotation ]
266- }
267- if vpcName != "" {
268- break LOOP
269- }
270- }
271- }
272- }
273- }
249+ if vpcName != "" && subnetName != "" {
250+ return vpcName , subnetName
274251 }
252+ }
275253
276- if vpcName != "" && subnetName != "" {
277- break
254+ for _ , slice := range endpointSlices {
255+ for _ , endpoint := range slice .Endpoints {
256+ if endpoint .TargetRef == nil {
257+ continue
258+ }
259+
260+ namespace := endpoint .TargetRef .Namespace
261+ name := endpoint .TargetRef .Name
262+
263+ pod , err := c .podsLister .Pods (namespace ).Get (name )
264+ if err != nil {
265+ err := fmt .Errorf ("couldn't retrieve pod %s/%s" , namespace , name )
266+ klog .Error (err )
267+ continue
268+ }
269+
270+ vpc , subnet , err := c .getEndpointVpcAndSubnet (pod , endpoint .Addresses )
271+ if err != nil {
272+ err := fmt .Errorf ("couldn't retrieve get subnet/vpc for pod %s/%s" , namespace , name )
273+ klog .Error (err )
274+ continue
275+ }
276+
277+ if vpcName == "" {
278+ vpcName = vpc
279+ }
280+
281+ if subnetName == "" {
282+ subnetName = subnet
283+ }
284+
285+ if vpcName != "" && subnetName != "" {
286+ return vpcName , subnetName
287+ }
278288 }
279289 }
280290
@@ -375,7 +385,14 @@ func (c *Controller) getIPPortMappingBackend(endpointSlices []*discoveryv1.Endpo
375385
376386 for _ , endpoint := range endpointSlice .Endpoints {
377387 if isGenIPPortMapping && endpoint .TargetRef .Name != "" {
378- lspName , err := c .getEndpointTargetLSP (endpoint .TargetRef .Name , endpoint .TargetRef .Namespace , endpoint .Addresses )
388+ pod , err := c .podsLister .Pods (endpoint .TargetRef .Namespace ).Get (endpoint .TargetRef .Name )
389+ if err != nil {
390+ err := fmt .Errorf ("failed to get pod %s/%s: %w" , endpoint .TargetRef .Namespace , endpoint .TargetRef .Name , err )
391+ klog .Error (err )
392+ continue
393+ }
394+
395+ lspName , err := c .getEndpointTargetLSPName (pod , endpoint .Addresses )
379396 if err != nil {
380397 err := fmt .Errorf ("couldn't get LSP for the endpoint's target: %w" , err )
381398 klog .Error (err )
@@ -408,6 +425,23 @@ func endpointReady(endpoint discoveryv1.Endpoint) bool {
408425 return endpoint .Conditions .Ready == nil || * endpoint .Conditions .Ready
409426}
410427
428+ // getPodProviders returns all the providers available on a pod
429+ func (c * Controller ) getPodProviders (pod * v1.Pod ) ([]string , error ) {
430+ // Get all the networks to which the pod is attached
431+ podNetworks , err := c .getPodKubeovnNets (pod )
432+ if err != nil {
433+ return nil , fmt .Errorf ("failed to get pod networks: %w" , err )
434+ }
435+
436+ // Retrieve all the providers
437+ var providers []string
438+ for _ , podNetwork := range podNetworks {
439+ providers = append (providers , podNetwork .ProviderName )
440+ }
441+
442+ return providers , nil
443+ }
444+
411445// getMatchingProviderForAddress returns the provider linked to a subnet in which a particular address is present
412446func getMatchingProviderForAddress (pod * v1.Pod , providers []string , address string ) string {
413447 if pod .Annotations == nil {
@@ -430,10 +464,29 @@ func getMatchingProviderForAddress(pod *v1.Pod, providers []string, address stri
430464 return ""
431465}
432466
433- // getEndpointTargetLSPName returns the name of the LSP for a pod targeted by an endpoint.
467+ // getEndpointProvider returns the provider linked to the addresses of an endpoint
468+ func (c * Controller ) getEndpointProvider (pod * v1.Pod , addresses []string ) (string , error ) {
469+ // Retrieve all the providers of the pod
470+ providers , err := c .getPodProviders (pod )
471+ if err != nil {
472+ return "" , err
473+ }
474+
475+ // Get the first matching provider for any of the address in the endpoint
476+ var provider string
477+ for _ , address := range addresses {
478+ if provider = getMatchingProviderForAddress (pod , providers , address ); provider != "" {
479+ return provider , nil
480+ }
481+ }
482+
483+ return "" , nil
484+ }
485+
486+ // getEndpointTargetLSPNameFromProvider returns the name of the LSP for a pod targeted by an endpoint.
434487// A custom provider can be specified if the LSP is within a subnet that doesn't use
435488// the default "ovn" provider.
436- func getEndpointTargetLSPName (pod * v1.Pod , provider string ) string {
489+ func getEndpointTargetLSPNameFromProvider (pod * v1.Pod , provider string ) string {
437490 // If no provider is specified, use the default one
438491 if provider == "" {
439492 provider = util .OvnProvider
@@ -451,32 +504,59 @@ func getEndpointTargetLSPName(pod *v1.Pod, provider string) string {
451504}
452505
453506// getEndpointTargetLSP returns the name of the LSP on which addresses are attached for a specific pod
454- func (c * Controller ) getEndpointTargetLSP (pod , namespace string , addresses []string ) (string , error ) {
455- // Retrieve the pod object from its namespace and name
456- podObj , err := c .podsLister . Pods ( namespace ). Get ( pod )
507+ func (c * Controller ) getEndpointTargetLSPName (pod * v1. Pod , addresses []string ) (string , error ) {
508+ // Retrieve the provider for those addresses
509+ provider , err := c .getEndpointProvider ( pod , addresses )
457510 if err != nil {
458- return "" , fmt . Errorf ( "failed to get pod %s/%s: %w" , namespace , pod , err )
511+ return "" , err
459512 }
460513
461- // Get all the networks to which the pod is attached
462- podNetworks , err := c .getPodKubeovnNets (podObj )
514+ return getEndpointTargetLSPNameFromProvider (pod , provider ), nil
515+ }
516+
517+ // getSubnetByProvider returns the subnet linked to a provider on a pod
518+ func (c * Controller ) getSubnetByProvider (pod * v1.Pod , provider string ) (string , error ) {
519+ subnetName , exists := pod .Annotations [fmt .Sprintf (util .LogicalSwitchAnnotationTemplate , provider )]
520+ if ! exists {
521+ return "" , fmt .Errorf ("couldn't find subnet linked to provider %s" , provider )
522+ }
523+
524+ return subnetName , nil
525+ }
526+
527+ // getVpcByProvider returns the VPC linked to a provider on a pod
528+ func (c * Controller ) getVpcByProvider (pod * v1.Pod , provider string ) (string , error ) {
529+ vpcName , exists := pod .Annotations [fmt .Sprintf (util .LogicalRouterAnnotationTemplate , provider )]
530+ if ! exists {
531+ return "" , fmt .Errorf ("couldn't find vpc linked to provider %s" , provider )
532+ }
533+
534+ return vpcName , nil
535+ }
536+
537+ // getEndpointVpcAndSubnet returns the VPC/subnet for a pod and a set of addresses attached to it
538+ func (c * Controller ) getEndpointVpcAndSubnet (pod * v1.Pod , addresses []string ) (string , string , error ) {
539+ // Retrieve the provider for those addresses
540+ provider , err := c .getEndpointProvider (pod , addresses )
463541 if err != nil {
464- return "" , fmt . Errorf ( "failed to get pod networks: %w " , err )
542+ return "" , " " , err
465543 }
466544
467- // Retrieve all the providers
468- var providers []string
469- for _ , podNetwork := range podNetworks {
470- providers = append (providers , podNetwork .ProviderName )
545+ if provider == "" {
546+ return "" , "" , nil
471547 }
472548
473- // Get the first matching provider for any of the address in the endpoint
474- var provider string
475- for _ , address := range addresses {
476- if provider = getMatchingProviderForAddress (podObj , providers , address ); provider != "" {
477- break
478- }
549+ // Retrieve the subnet
550+ subnet , err := c .getSubnetByProvider (pod , provider )
551+ if err != nil {
552+ return "" , "" , err
553+ }
554+
555+ // Retrieve the VPC
556+ vpc , err := c .getVpcByProvider (pod , provider )
557+ if err != nil {
558+ return "" , "" , err
479559 }
480560
481- return getEndpointTargetLSPName ( podObj , provider ) , nil
561+ return vpc , subnet , nil
482562}
0 commit comments