diff --git a/provider/kubernetes.go b/provider/kubernetes.go index 9747d60e1..0e845b42a 100644 --- a/provider/kubernetes.go +++ b/provider/kubernetes.go @@ -193,28 +193,38 @@ func (provider *Kubernetes) loadIngresses(k8sClient k8s.Client) (*types.Configur if port.Port == 443 { protocol = "https" } - endpoints, exists, err := k8sClient.GetEndpoints(service.ObjectMeta.Namespace, service.ObjectMeta.Name) - if err != nil || !exists { - log.Errorf("Error retrieving endpoints %s/%s: %v", service.ObjectMeta.Namespace, service.ObjectMeta.Name, err) - continue - } - if len(endpoints.Subsets) == 0 { - log.Warnf("Endpoints not found for %s/%s, falling back to Service ClusterIP", service.ObjectMeta.Namespace, service.ObjectMeta.Name) - templateObjects.Backends[r.Host+pa.Path].Servers[string(service.UID)] = types.Server{ - URL: protocol + "://" + service.Spec.ClusterIP + ":" + strconv.Itoa(int(port.Port)), + if service.Spec.Type == "ExternalName" { + url := protocol + "://" + service.Spec.ExternalName + name := url + + templateObjects.Backends[r.Host+pa.Path].Servers[name] = types.Server{ + URL: url, Weight: 1, } } else { - for _, subset := range endpoints.Subsets { - for _, address := range subset.Addresses { - url := protocol + "://" + address.IP + ":" + strconv.Itoa(endpointPortNumber(port, subset.Ports)) - name := url - if address.TargetRef != nil && address.TargetRef.Name != "" { - name = address.TargetRef.Name - } - templateObjects.Backends[r.Host+pa.Path].Servers[name] = types.Server{ - URL: url, - Weight: 1, + endpoints, exists, err := k8sClient.GetEndpoints(service.ObjectMeta.Namespace, service.ObjectMeta.Name) + if err != nil || !exists { + log.Errorf("Error retrieving endpoints %s/%s: %v", service.ObjectMeta.Namespace, service.ObjectMeta.Name, err) + continue + } + if len(endpoints.Subsets) == 0 { + log.Warnf("Endpoints not found for %s/%s, falling back to Service ClusterIP", service.ObjectMeta.Namespace, service.ObjectMeta.Name) + templateObjects.Backends[r.Host+pa.Path].Servers[string(service.UID)] = types.Server{ + URL: protocol + "://" + service.Spec.ClusterIP + ":" + strconv.Itoa(int(port.Port)), + Weight: 1, + } + } else { + for _, subset := range endpoints.Subsets { + for _, address := range subset.Addresses { + url := protocol + "://" + address.IP + ":" + strconv.Itoa(endpointPortNumber(port, subset.Ports)) + name := url + if address.TargetRef != nil && address.TargetRef.Name != "" { + name = address.TargetRef.Name + } + templateObjects.Backends[r.Host+pa.Path].Servers[name] = types.Server{ + URL: url, + Weight: 1, + } } } } diff --git a/provider/kubernetes_test.go b/provider/kubernetes_test.go index a3866f9cc..572facd18 100644 --- a/provider/kubernetes_test.go +++ b/provider/kubernetes_test.go @@ -31,6 +31,13 @@ func TestLoadIngresses(t *testing.T) { ServicePort: intstr.FromInt(80), }, }, + { + Path: "/namedthing", + Backend: v1beta1.IngressBackend{ + ServiceName: "service4", + ServicePort: intstr.FromString("https"), + }, + }, }, }, }, @@ -110,6 +117,24 @@ func TestLoadIngresses(t *testing.T) { }, }, }, + { + ObjectMeta: v1.ObjectMeta{ + Name: "service4", + UID: "4", + Namespace: "testing", + }, + Spec: v1.ServiceSpec{ + ClusterIP: "10.0.0.4", + Type: "ExternalName", + ExternalName: "example.com", + Ports: []v1.ServicePort{ + { + Name: "https", + Port: 443, + }, + }, + }, + }, } endpoints := []*v1.Endpoints{ { @@ -221,6 +246,19 @@ func TestLoadIngresses(t *testing.T) { Method: "wrr", }, }, + "foo/namedthing": { + Servers: map[string]types.Server{ + "https://example.com": { + URL: "https://example.com", + Weight: 1, + }, + }, + CircuitBreaker: nil, + LoadBalancer: &types.LoadBalancer{ + Sticky: false, + Method: "wrr", + }, + }, "bar": { Servers: map[string]types.Server{ "2": { @@ -257,6 +295,19 @@ func TestLoadIngresses(t *testing.T) { }, }, }, + "foo/namedthing": { + Backend: "foo/namedthing", + PassHostHeader: true, + Priority: len("/namedthing"), + Routes: map[string]types.Route{ + "/namedthing": { + Rule: "PathPrefix:/namedthing", + }, + "foo": { + Rule: "Host:foo", + }, + }, + }, "bar": { Backend: "bar", PassHostHeader: true,