@@ -26,11 +26,14 @@ import (
26
26
27
27
"github.com/nginxinc/kubernetes-ingress/nginx-controller/nginx"
28
28
"k8s.io/kubernetes/pkg/api"
29
+ podutil "k8s.io/kubernetes/pkg/api/pod"
29
30
"k8s.io/kubernetes/pkg/apis/extensions"
30
31
"k8s.io/kubernetes/pkg/client/cache"
31
32
client "k8s.io/kubernetes/pkg/client/unversioned"
32
33
"k8s.io/kubernetes/pkg/controller/framework"
34
+ "k8s.io/kubernetes/pkg/labels"
33
35
"k8s.io/kubernetes/pkg/runtime"
36
+ "k8s.io/kubernetes/pkg/util/intstr"
34
37
"k8s.io/kubernetes/pkg/watch"
35
38
)
36
39
@@ -384,13 +387,13 @@ func (lbc *LoadBalancerController) createIngress(ing *extensions.Ingress) nginx.
384
387
ingEx .Secrets [secretName ] = secret
385
388
}
386
389
387
- ingEx .Endpoints = make (map [string ]* api. Endpoints )
390
+ ingEx .Endpoints = make (map [string ][] string )
388
391
if ing .Spec .Backend != nil {
389
392
endps , err := lbc .getEndpointsForIngressBackend (ing .Spec .Backend , ing .Namespace )
390
393
if err != nil {
391
- glog .V ( 3 ). Infof ( "Error retrieving endpoints for the services %v: %v" , ing .Spec .Backend .ServiceName , err )
394
+ glog .Warningf ( "Error retrieving endpoints for the service %v: %v" , ing .Spec .Backend .ServiceName , err )
392
395
} else {
393
- ingEx .Endpoints [ing .Spec .Backend .ServiceName ] = endps
396
+ ingEx .Endpoints [ing .Spec .Backend .ServiceName + ing . Spec . Backend . ServicePort . String () ] = endps
394
397
}
395
398
}
396
399
@@ -402,35 +405,113 @@ func (lbc *LoadBalancerController) createIngress(ing *extensions.Ingress) nginx.
402
405
for _ , path := range rule .HTTP .Paths {
403
406
endps , err := lbc .getEndpointsForIngressBackend (& path .Backend , ing .Namespace )
404
407
if err != nil {
405
- glog .V ( 3 ). Infof ( "Error retrieving endpoints for the services %v: %v" , path .Backend .ServiceName , err )
408
+ glog .Warningf ( "Error retrieving endpoints for the service %v: %v" , path .Backend .ServiceName , err )
406
409
} else {
407
- ingEx .Endpoints [path .Backend .ServiceName ] = endps
410
+ ingEx .Endpoints [path .Backend .ServiceName + path . Backend . ServicePort . String () ] = endps
408
411
}
409
-
410
412
}
411
413
}
412
414
413
415
return ingEx
414
416
}
415
417
416
- func (lbc * LoadBalancerController ) getEndpointsForIngressBackend (backend * extensions.IngressBackend , namespace string ) (* api.Endpoints , error ) {
418
+ func (lbc * LoadBalancerController ) getEndpointsForIngressBackend (backend * extensions.IngressBackend , namespace string ) ([]string , error ) {
419
+ svc , err := lbc .getServiceForIngressBackend (backend , namespace )
420
+ if err != nil {
421
+ glog .V (3 ).Infof ("Error getting service %v: %v" , backend .ServiceName , err )
422
+ return nil , err
423
+ }
424
+
425
+ endps , err := lbc .endpLister .GetServiceEndpoints (svc )
426
+ if err != nil {
427
+ glog .V (3 ).Infof ("Error getting endpoints for service %s from the cache: %v" , svc .Name , err )
428
+ return nil , err
429
+ }
430
+
431
+ result , err := lbc .getEndpointsForPort (endps , backend .ServicePort , svc )
432
+ if err != nil {
433
+ glog .V (3 ).Infof ("Error getting endpoints for service %s port %v: %v" , svc .Name , backend .ServicePort , err )
434
+ return nil , err
435
+ }
436
+ return result , nil
437
+ }
438
+
439
+ func (lbc * LoadBalancerController ) getEndpointsForPort (endps api.Endpoints , ingSvcPort intstr.IntOrString , svc * api.Service ) ([]string , error ) {
440
+ var targetPort int
441
+ var err error
442
+ found := false
443
+
444
+ for _ , port := range svc .Spec .Ports {
445
+ if (ingSvcPort .Type == intstr .Int && port .Port == ingSvcPort .IntValue ()) || (ingSvcPort .Type == intstr .String && port .Name == ingSvcPort .String ()) {
446
+ targetPort , err = lbc .getTargetPort (& port , svc )
447
+ if err != nil {
448
+ return nil , fmt .Errorf ("Error determining target port for port %v in Ingress: %v" , ingSvcPort , err )
449
+ }
450
+ found = true
451
+ break
452
+ }
453
+ }
454
+
455
+ if ! found {
456
+ return nil , fmt .Errorf ("No port %v in service %s" , ingSvcPort , svc .Name )
457
+ }
458
+
459
+ for _ , subset := range endps .Subsets {
460
+ for _ , port := range subset .Ports {
461
+ if port .Port == targetPort {
462
+ var endpoints []string
463
+ for _ , address := range subset .Addresses {
464
+ endpoint := fmt .Sprintf ("%v:%v" , address .IP , port .Port )
465
+ endpoints = append (endpoints , endpoint )
466
+ }
467
+ return endpoints , nil
468
+ }
469
+ }
470
+ }
471
+
472
+ return nil , fmt .Errorf ("No endpoints for target port %v in service %s" , targetPort , svc .Name )
473
+ }
474
+
475
+ func (lbc * LoadBalancerController ) getTargetPort (svcPort * api.ServicePort , svc * api.Service ) (int , error ) {
476
+ if (svcPort .TargetPort == intstr.IntOrString {}) {
477
+ return svcPort .Port , nil
478
+ }
479
+
480
+ if svcPort .TargetPort .Type == intstr .Int {
481
+ return svcPort .TargetPort .IntValue (), nil
482
+ }
483
+
484
+ pods , err := lbc .client .Pods (svc .Namespace ).List (api.ListOptions {LabelSelector : labels .Set (svc .Spec .Selector ).AsSelector ()})
485
+ if err != nil {
486
+ return 0 , fmt .Errorf ("Error getting pod information: %v" , err )
487
+ }
488
+
489
+ if len (pods .Items ) == 0 {
490
+ return 0 , fmt .Errorf ("No pods of service %s" , svc .Name )
491
+ }
492
+
493
+ pod := & pods .Items [0 ]
494
+
495
+ portNum , err := podutil .FindPort (pod , svcPort )
496
+ if err != nil {
497
+ return 0 , fmt .Errorf ("Error finding named port %v in pod %s: %v" , svcPort , pod .Name , err )
498
+ }
499
+
500
+ return portNum , nil
501
+ }
502
+
503
+ func (lbc * LoadBalancerController ) getServiceForIngressBackend (backend * extensions.IngressBackend , namespace string ) (* api.Service , error ) {
417
504
svcKey := namespace + "/" + backend .ServiceName
418
505
svcObj , svcExists , err := lbc .svcLister .Store .GetByKey (svcKey )
419
506
if err != nil {
420
- glog .V (3 ).Infof ("error getting service %v from the cache: %v" , svcKey , err )
421
507
return nil , err
422
508
}
509
+
423
510
if svcExists {
424
- svc := svcObj .(* api.Service )
425
- endps , err := lbc .endpLister .GetServiceEndpoints (svc )
426
- if err != nil {
427
- glog .V (3 ).Infof ("error getting endpoints for service %v from the cache: %v" , svc , err )
428
- return nil , err
429
- }
430
- return & endps , nil
511
+ return svcObj .(* api.Service ), nil
431
512
}
432
- return nil , fmt .Errorf ("service %s doesn't exists" , svcKey )
433
513
514
+ return nil , fmt .Errorf ("service %s doesn't exists" , svcKey )
434
515
}
435
516
436
517
func parseNginxConfigMaps (nginxConfigMaps string ) (string , string , error ) {
0 commit comments