Merge pull request #334 from containous/fix-k8s-watch-ssl

Fix Kubernetes watch SSL & empty schema
This commit is contained in:
Vincent Demeester 2016-04-27 10:20:26 +02:00
commit 2f5c9273ee
5 changed files with 31 additions and 36 deletions

View file

@ -13,7 +13,7 @@
Træfɪk is a modern HTTP reverse proxy and load balancer made to deploy microservices with ease.
It supports several backends ([Docker](https://www.docker.com/), [Swarm](https://docs.docker.com/swarm), [Mesos/Marathon](https://mesosphere.github.io/marathon/), [Consul](https://www.consul.io/), [Etcd](https://coreos.com/etcd/), [Zookeeper](https://zookeeper.apache.org), [BoltDB](https://github.com/boltdb/bolt), Rest API, file...) to manage its configuration automatically and dynamically.
It supports several backends ([Docker](https://www.docker.com/), [Swarm](https://docs.docker.com/swarm), [Mesos/Marathon](https://mesosphere.github.io/marathon/), [Kubernetes](http://kubernetes.io/), [Consul](https://www.consul.io/), [Etcd](https://coreos.com/etcd/), [Zookeeper](https://zookeeper.apache.org), [BoltDB](https://github.com/boltdb/bolt), Rest API, file...) to manage its configuration automatically and dynamically.
## Overview
@ -133,8 +133,11 @@ Europe. We provide consulting, development, training and support for the world
software products.
[![Asteris](docs/img/asteris.logo.png)](https://aster.is)
Founded in 2014, Asteris creates next-generation infrastructure software for the modern datacenter. Asteris writes software that makes it easy for companies to implement continuous delivery and realtime data pipelines. We support the HashiCorp stack, along with Kubernetes, Apache Mesos, Spark and Kafka. We're core committers on mantl.io, consul-cli and mesos-consul.
.
## Credits
Thanks you [Peka](http://peka.byethost11.com/photoblog/) for your awesome work on the logo ![logo](docs/img/traefik.icon.png)

View file

@ -12,7 +12,7 @@ spec:
nodePort: 30283
targetPort: 80
protocol: TCP
name: http
name: https
selector:
app: whoami
---

View file

@ -7,11 +7,9 @@ import (
"fmt"
"github.com/containous/traefik/safe"
"github.com/parnurzeal/gorequest"
"net"
"net/http"
"net/url"
"strings"
"time"
)
const (
@ -57,7 +55,7 @@ func (c *clientImpl) GetIngresses(predicate func(Ingress) bool) ([]Ingress, erro
body, err := c.do(c.request(getURL))
if err != nil {
return nil, fmt.Errorf("failed to create request: GET %q : %v", getURL, err)
return nil, fmt.Errorf("failed to create ingresses request: GET %q : %v", getURL, err)
}
var ingressList IngressList
@ -85,7 +83,7 @@ func (c *clientImpl) GetServices(predicate func(Service) bool) ([]Service, error
body, err := c.do(c.request(getURL))
if err != nil {
return nil, fmt.Errorf("failed to create request: GET %q : %v", getURL, err)
return nil, fmt.Errorf("failed to create services request: GET %q : %v", getURL, err)
}
var serviceList ServiceList
@ -133,22 +131,22 @@ func (c *clientImpl) WatchAll(stopCh <-chan bool) (chan interface{}, chan error,
stopIngresses := make(chan bool)
chanIngresses, chanIngressesErr, err := c.WatchIngresses(stopIngresses)
if err != nil {
return watchCh, errCh, fmt.Errorf("failed to create watch %v", err)
return watchCh, errCh, fmt.Errorf("failed to create watch: %v", err)
}
stopServices := make(chan bool)
chanServices, chanServicesErr, err := c.WatchServices(stopServices)
if err != nil {
return watchCh, errCh, fmt.Errorf("failed to create watch %v", err)
return watchCh, errCh, fmt.Errorf("failed to create watch: %v", err)
}
stopPods := make(chan bool)
chanPods, chanPodsErr, err := c.WatchPods(stopPods)
if err != nil {
return watchCh, errCh, fmt.Errorf("failed to create watch %v", err)
return watchCh, errCh, fmt.Errorf("failed to create watch: %v", err)
}
stopReplicationControllers := make(chan bool)
chanReplicationControllers, chanReplicationControllersErr, err := c.WatchReplicationControllers(stopReplicationControllers)
if err != nil {
return watchCh, errCh, fmt.Errorf("failed to create watch %v", err)
return watchCh, errCh, fmt.Errorf("failed to create watch: %v", err)
}
go func() {
defer close(watchCh)
@ -225,34 +223,26 @@ func (c *clientImpl) watch(url string, stopCh <-chan bool) (chan interface{}, ch
// get version
body, err := c.do(c.request(url))
if err != nil {
return watchCh, errCh, fmt.Errorf("failed to create request: GET %q : %v", url, err)
return watchCh, errCh, fmt.Errorf("failed to do version request: GET %q : %v", url, err)
}
var generic GenericObject
if err := json.Unmarshal(body, &generic); err != nil {
return watchCh, errCh, fmt.Errorf("failed to create request: GET %q : %v", url, err)
return watchCh, errCh, fmt.Errorf("failed to decode version %v", err)
}
resourceVersion := generic.ResourceVersion
url = url + "?watch&resourceVersion=" + resourceVersion
// Make request to Kubernetes API
request := c.request(url)
request.Transport.Dial = func(network, addr string) (net.Conn, error) {
conn, err := net.Dial(network, addr)
if err != nil {
return nil, err
}
// No timeout for long-polling request
conn.SetDeadline(time.Now())
return conn, nil
}
req, err := request.TLSClientConfig(c.tls).MakeRequest()
req, err := request.MakeRequest()
if err != nil {
return watchCh, errCh, fmt.Errorf("failed to create request: GET %q : %v", url, err)
return watchCh, errCh, fmt.Errorf("failed to make watch request: GET %q : %v", url, err)
}
request.Client.Transport = request.Transport
res, err := request.Client.Do(req)
if err != nil {
return watchCh, errCh, fmt.Errorf("failed to make request: GET %q: %v", url, err)
return watchCh, errCh, fmt.Errorf("failed to do watch request: GET %q: %v", url, err)
}
shouldStop := safe.New(false)

View file

@ -170,10 +170,12 @@ func (provider *Kubernetes) loadIngresses(k8sClient k8s.Client) (*types.Configur
log.Errorf("Error retrieving services %s", pa.Backend.ServiceName)
}
for _, service := range services {
var protocol string
protocol := "http"
for _, port := range service.Spec.Ports {
if port.Port == pa.Backend.ServicePort.IntValue() {
protocol = port.Name
if port.Port == 443 {
protocol = "https"
}
templateObjects.Backends[r.Host+pa.Path].Servers[string(service.UID)] = types.Server{
URL: protocol + "://" + service.Spec.ClusterIP + ":" + pa.Backend.ServicePort.String(),
Weight: 1,

View file

@ -1,6 +1,7 @@
package provider
import (
"encoding/json"
"github.com/containous/traefik/provider/k8s"
"github.com/containous/traefik/types"
"reflect"
@ -35,7 +36,7 @@ func TestLoadIngresses(t *testing.T) {
{
Backend: k8s.IngressBackend{
ServiceName: "service3",
ServicePort: k8s.FromInt(803),
ServicePort: k8s.FromInt(443),
},
},
{
@ -76,7 +77,6 @@ func TestLoadIngresses(t *testing.T) {
ClusterIP: "10.0.0.2",
Ports: []k8s.ServicePort{
{
Name: "http",
Port: 802,
},
},
@ -92,7 +92,7 @@ func TestLoadIngresses(t *testing.T) {
Ports: []k8s.ServicePort{
{
Name: "http",
Port: 803,
Port: 443,
},
},
},
@ -129,7 +129,7 @@ func TestLoadIngresses(t *testing.T) {
Weight: 1,
},
"3": {
URL: "http://10.0.0.3:803",
URL: "https://10.0.0.3:443",
Weight: 1,
},
},
@ -159,11 +159,11 @@ func TestLoadIngresses(t *testing.T) {
},
},
}
if !reflect.DeepEqual(actual.Backends, expected.Backends) {
t.Fatalf("expected %+v, got %+v", expected.Backends, actual.Backends)
}
if !reflect.DeepEqual(actual.Frontends, expected.Frontends) {
t.Fatalf("expected %+v, got %+v", expected.Frontends, actual.Frontends)
actualJSON, _ := json.Marshal(actual)
expectedJSON, _ := json.Marshal(expected)
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("expected %+v, got %+v", string(expectedJSON), string(actualJSON))
}
}