@@ -21,15 +21,16 @@ import (
2121)
2222
2323const (
24- podIPIndexField = "ip"
25- endpointIPPortIndexField = "ipPort"
26- serviceIPIndexField = "spec.ip"
27- externalIPIndexField = "spec.externalIPs"
28- portNumberIndexField = "service.spec.ports.nodePort"
29- nodeIPIndexField = "node.status.Addresses.ExternalIP"
30- IstioCanonicalNameLabelKey = "service.istio.io/canonical-name"
31- apiServerName = "kubernetes"
32- apiServerNamespace = "default"
24+ podIPIndexField = "ip"
25+ podIPIncludingHostNetworkIndexField = "ipAndHostNetwork"
26+ endpointIPPortIndexField = "ipPort"
27+ serviceIPIndexField = "spec.ip"
28+ externalIPIndexField = "spec.externalIPs"
29+ nodePortNumberIndexField = "service.spec.ports.nodePort"
30+ nodeIPIndexField = "node.status.Addresses.ExternalIP"
31+ IstioCanonicalNameLabelKey = "service.istio.io/canonical-name"
32+ apiServerName = "kubernetes"
33+ apiServerNamespace = "default"
3334)
3435
3536type KubeFinder struct {
@@ -70,6 +71,23 @@ func (k *KubeFinder) initIndexes(ctx context.Context) error {
7071 return errors .Wrap (err )
7172 }
7273
74+ err = k .mgr .GetCache ().IndexField (ctx , & corev1.Pod {}, podIPIncludingHostNetworkIndexField , func (object client.Object ) []string {
75+ res := make ([]string , 0 )
76+ pod := object .(* corev1.Pod )
77+
78+ if pod .DeletionTimestamp != nil {
79+ return res
80+ }
81+
82+ for _ , ip := range pod .Status .PodIPs {
83+ res = append (res , ip .IP )
84+ }
85+ return res
86+ })
87+ if err != nil {
88+ return errors .Wrap (err )
89+ }
90+
7391 err = k .mgr .GetCache ().IndexField (ctx , & corev1.Service {}, serviceIPIndexField , func (object client.Object ) []string {
7492 res := make ([]string , 0 )
7593 svc := object .(* corev1.Service )
@@ -99,13 +117,15 @@ func (k *KubeFinder) initIndexes(ctx context.Context) error {
99117 return errors .Wrap (err )
100118 }
101119
102- err = k .mgr .GetCache ().IndexField (ctx , & corev1.Service {}, portNumberIndexField , func (object client.Object ) []string {
120+ err = k .mgr .GetCache ().IndexField (ctx , & corev1.Service {}, nodePortNumberIndexField , func (object client.Object ) []string {
121+ // node ports are unique per service - so it can be used for indexing services
103122 ports := sets .New [string ]()
104123 svc := object .(* corev1.Service )
105124 if svc .DeletionTimestamp != nil {
106125 return nil
107126 }
108- if svc .Spec .Type != corev1 .ServiceTypeNodePort {
127+ // Only node port and load balancer typed services use node ports
128+ if svc .Spec .Type != corev1 .ServiceTypeNodePort && svc .Spec .Type != corev1 .ServiceTypeLoadBalancer {
109129 return nil
110130 }
111131
@@ -252,22 +272,22 @@ func (k *KubeFinder) ResolveIPToControlPlane(ctx context.Context, ip string) (*c
252272}
253273
254274func (k * KubeFinder ) ResolveIPToExternalAccessService (ctx context.Context , ip string , port int ) (* corev1.Service , bool , error ) {
255- nodePortService , ok , err := k .resolveNodePortService (ctx , ip , port )
275+ nodePortService , ok , err := k .resolveServiceByNodeIPAndPort (ctx , ip , port )
256276 if err != nil {
257277 return nil , false , errors .Wrap (err )
258278 }
259279 if ok {
260280 return nodePortService , true , nil
261281 }
262282
263- loadBalancerService , ok , err := k .resolveLoadBalancerService (ctx , ip , port )
283+ loadBalancerService , ok , err := k .resolveLoadBalancerServiceByExternalIP (ctx , ip , port )
264284 if err != nil {
265285 return nil , false , errors .Wrap (err )
266286 }
267287 return loadBalancerService , ok , nil
268288}
269289
270- func (k * KubeFinder ) resolveLoadBalancerService (ctx context.Context , ip string , port int ) (* corev1.Service , bool , error ) {
290+ func (k * KubeFinder ) resolveLoadBalancerServiceByExternalIP (ctx context.Context , ip string , port int ) (* corev1.Service , bool , error ) {
271291 var services corev1.ServiceList
272292 err := k .client .List (ctx , & services , client.MatchingFields {externalIPIndexField : ip })
273293 if err != nil {
@@ -288,7 +308,7 @@ func (k *KubeFinder) resolveLoadBalancerService(ctx context.Context, ip string,
288308 return & service , true , nil
289309}
290310
291- func (k * KubeFinder ) resolveNodePortService (ctx context.Context , ip string , port int ) (* corev1.Service , bool , error ) {
311+ func (k * KubeFinder ) resolveServiceByNodeIPAndPort (ctx context.Context , ip string , port int ) (* corev1.Service , bool , error ) {
292312 var nodes corev1.NodeList
293313 err := k .client .List (ctx , & nodes , client.MatchingFields {nodeIPIndexField : ip })
294314 if err != nil {
@@ -304,7 +324,7 @@ func (k *KubeFinder) resolveNodePortService(ctx context.Context, ip string, port
304324
305325 portString := fmt .Sprintf ("%d" , port )
306326 var services corev1.ServiceList
307- err = k .client .List (ctx , & services , client.MatchingFields {portNumberIndexField : portString })
327+ err = k .client .List (ctx , & services , client.MatchingFields {nodePortNumberIndexField : portString })
308328 if err != nil {
309329 return nil , false , errors .Wrap (err )
310330 }
@@ -442,3 +462,51 @@ func (k *KubeFinder) ResolveOtterizeIdentityForService(ctx context.Context, svc
442462 dstSvcIdentity .KubernetesService = lo .ToPtr (svc .Name )
443463 return dstSvcIdentity , true , nil
444464}
465+
466+ func (k * KubeFinder ) IsSrcIpClusterInternal (ctx context.Context , ip string ) (bool , error ) {
467+ // Known issue: this function is currently missing support for services/endpoints, node.PodCIDR, and pods that were deleted.
468+
469+ isNode , err := k .IsNodeIP (ctx , ip )
470+ if err != nil {
471+ return false , errors .Wrap (err )
472+ }
473+ if isNode {
474+ return true , nil
475+ }
476+
477+ isPod , err := k .IsPodIp (ctx , ip )
478+ if err != nil {
479+ return false , errors .Wrap (err )
480+ }
481+ if isPod {
482+ return true , nil
483+ }
484+
485+ _ , isControlPlane , err := k .ResolveIPToControlPlane (ctx , ip )
486+ if err != nil {
487+ return false , errors .Wrap (err )
488+ }
489+ if isControlPlane {
490+ return true , nil
491+ }
492+
493+ return false , nil
494+ }
495+
496+ func (k * KubeFinder ) IsPodIp (ctx context.Context , ip string ) (bool , error ) {
497+ var pods corev1.PodList
498+ err := k .client .List (ctx , & pods , client.MatchingFields {podIPIncludingHostNetworkIndexField : ip })
499+ if err != nil {
500+ return false , errors .Wrap (err )
501+ }
502+ return len (pods .Items ) > 0 , nil
503+ }
504+
505+ func (k * KubeFinder ) IsNodeIP (ctx context.Context , ip string ) (bool , error ) {
506+ var nodes corev1.NodeList
507+ err := k .client .List (ctx , & nodes , client.MatchingFields {nodeIPIndexField : ip })
508+ if err != nil {
509+ return false , errors .Wrap (err )
510+ }
511+ return len (nodes .Items ) > 0 , nil
512+ }
0 commit comments