Add TLS support for etcd and consul
This commit is contained in:
parent
e26e0955b3
commit
b83fb525a8
8 changed files with 197 additions and 27 deletions
14
glide.lock
generated
14
glide.lock
generated
|
@ -1,5 +1,5 @@
|
|||
hash: cf8f42aae193bd26b7670157094e6b11590443bc500f0a78243ee21bd3ed314e
|
||||
updated: 2016-06-23T17:46:42.381770076+02:00
|
||||
hash: 70ad4e576bc1fa845512cce6b4ade5c422ba4fb5bb0472b37e1d3a93f13809cd
|
||||
updated: 2016-07-07T17:33:16.358775373+02:00
|
||||
imports:
|
||||
- name: github.com/boltdb/bolt
|
||||
version: 3f7947a25d970e1e5f512276c14d5dcf731ccd5e
|
||||
|
@ -36,7 +36,7 @@ imports:
|
|||
subpackages:
|
||||
- spew
|
||||
- name: github.com/docker/distribution
|
||||
version: edd7cb5249d0a45262b20bb58b838ecf4fb368bd
|
||||
version: 4e17ab5d319ac5b70b2769442947567a83386fbc
|
||||
subpackages:
|
||||
- reference
|
||||
- digest
|
||||
|
@ -100,7 +100,7 @@ imports:
|
|||
- name: github.com/gorilla/context
|
||||
version: aed02d124ae4a0e94fea4541c8effd05bf0c8296
|
||||
- name: github.com/hashicorp/consul
|
||||
version: 6e061b2d580d80347b7c5c4dfc8730de7403a145
|
||||
version: 64e3033d3c7f80af3f925f4665a9bc1af75d6153
|
||||
subpackages:
|
||||
- api
|
||||
- name: github.com/hashicorp/go-cleanhttp
|
||||
|
@ -134,7 +134,7 @@ imports:
|
|||
- name: github.com/Microsoft/go-winio
|
||||
version: ce2922f643c8fd76b46cadc7f404a06282678b34
|
||||
- name: github.com/miekg/dns
|
||||
version: 48ab6605c66ac797e07f615101c3e9e10e932b66
|
||||
version: 5d001d020961ae1c184f9f8152fdc73810481677
|
||||
- name: github.com/mitchellh/mapstructure
|
||||
version: d2dd0262208475919e1a362f675cfc0e7c10e905
|
||||
- name: github.com/moul/http2curl
|
||||
|
@ -142,7 +142,7 @@ imports:
|
|||
- name: github.com/ogier/pflag
|
||||
version: 45c278ab3607870051a2ea9040bb85fcb8557481
|
||||
- name: github.com/opencontainers/runc
|
||||
version: 5dc3f3576efb5262bf582217e93f86c93944374d
|
||||
version: 9d7831e41d3ef428b67685eeb27f2b4a22a92391
|
||||
subpackages:
|
||||
- libcontainer/user
|
||||
- name: github.com/parnurzeal/gorequest
|
||||
|
@ -219,7 +219,7 @@ imports:
|
|||
subpackages:
|
||||
- acme
|
||||
- name: golang.org/x/crypto
|
||||
version: f3241ce8505855877cc8a9717bd61a0f7c4ea83c
|
||||
version: d81fdb778bf2c40a91b24519d60cdc5767318829
|
||||
subpackages:
|
||||
- ocsp
|
||||
- name: golang.org/x/net
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
|
||||
"errors"
|
||||
"github.com/containous/traefik/integration/utils"
|
||||
"github.com/containous/traefik/provider"
|
||||
checker "github.com/vdemeester/shakers"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
@ -24,7 +25,7 @@ type ConsulSuite struct {
|
|||
kv store.Store
|
||||
}
|
||||
|
||||
func (s *ConsulSuite) SetUpTest(c *check.C) {
|
||||
func (s *ConsulSuite) setupConsul(c *check.C) {
|
||||
s.createComposeProject(c, "consul")
|
||||
s.composeProject.Start(c)
|
||||
|
||||
|
@ -52,6 +53,45 @@ func (s *ConsulSuite) SetUpTest(c *check.C) {
|
|||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *ConsulSuite) setupConsulTLS(c *check.C) {
|
||||
s.createComposeProject(c, "consul_tls")
|
||||
s.composeProject.Start(c)
|
||||
|
||||
consul.Register()
|
||||
clientTLS := &provider.ClientTLS{
|
||||
CA: "resources/tls/ca.cert",
|
||||
Cert: "resources/tls/consul.cert",
|
||||
Key: "resources/tls/consul.key",
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
TLSConfig, err := clientTLS.CreateTLSConfig()
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
kv, err := libkv.NewStore(
|
||||
store.CONSUL,
|
||||
[]string{s.composeProject.Container(c, "consul").NetworkSettings.IPAddress + ":8585"},
|
||||
&store.Config{
|
||||
ConnectionTimeout: 10 * time.Second,
|
||||
TLS: TLSConfig,
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
c.Fatal("Cannot create store consul")
|
||||
}
|
||||
s.kv = kv
|
||||
|
||||
// wait for consul
|
||||
err = utils.Try(60*time.Second, func() error {
|
||||
_, err := kv.Exists("test")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *ConsulSuite) TearDownTest(c *check.C) {
|
||||
// shutdown and delete compose project
|
||||
if s.composeProject != nil {
|
||||
|
@ -62,6 +102,7 @@ func (s *ConsulSuite) TearDownTest(c *check.C) {
|
|||
func (s *ConsulSuite) TearDownSuite(c *check.C) {}
|
||||
|
||||
func (s *ConsulSuite) TestSimpleConfiguration(c *check.C) {
|
||||
s.setupConsul(c)
|
||||
consulHost := s.composeProject.Container(c, "consul").NetworkSettings.IPAddress
|
||||
file := s.adaptFile(c, "fixtures/consul/simple.toml", struct{ ConsulHost string }{consulHost})
|
||||
defer os.Remove(file)
|
||||
|
@ -79,6 +120,7 @@ func (s *ConsulSuite) TestSimpleConfiguration(c *check.C) {
|
|||
}
|
||||
|
||||
func (s *ConsulSuite) TestNominalConfiguration(c *check.C) {
|
||||
s.setupConsul(c)
|
||||
consulHost := s.composeProject.Container(c, "consul").NetworkSettings.IPAddress
|
||||
file := s.adaptFile(c, "fixtures/consul/simple.toml", struct{ ConsulHost string }{consulHost})
|
||||
defer os.Remove(file)
|
||||
|
@ -201,6 +243,7 @@ func (s *ConsulSuite) TestNominalConfiguration(c *check.C) {
|
|||
}
|
||||
|
||||
func (s *ConsulSuite) TestGlobalConfiguration(c *check.C) {
|
||||
s.setupConsul(c)
|
||||
consulHost := s.composeProject.Container(c, "consul").NetworkSettings.IPAddress
|
||||
err := s.kv.Put("traefik/entrypoints/http/address", []byte(":8001"), nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
@ -305,3 +348,46 @@ func (s *ConsulSuite) TestGlobalConfiguration(c *check.C) {
|
|||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(response.StatusCode, checker.Equals, 200)
|
||||
}
|
||||
|
||||
func (s *ConsulSuite) TestGlobalConfigurationWithClientTLS(c *check.C) {
|
||||
s.setupConsulTLS(c)
|
||||
consulHost := s.composeProject.Container(c, "consul").NetworkSettings.IPAddress
|
||||
|
||||
err := s.kv.Put("traefik/web/address", []byte(":8081"), nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// wait for consul
|
||||
err = utils.Try(60*time.Second, func() error {
|
||||
_, err := s.kv.Exists("traefik/web/address")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// start traefik
|
||||
cmd := exec.Command(traefikBinary, "--configFile=fixtures/simple_web.toml",
|
||||
"--consul", "--consul.endpoint="+consulHost+":8585",
|
||||
"--consul.tls.ca=resources/tls/ca.cert",
|
||||
"--consul.tls.cert=resources/tls/consul.cert",
|
||||
"--consul.tls.key=resources/tls/consul.key",
|
||||
"--consul.tls.insecureskipverify")
|
||||
// cmd.Stdout = os.Stdout
|
||||
// cmd.Stderr = os.Stderr
|
||||
|
||||
err = cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
// wait for traefik
|
||||
err = utils.TryRequest("http://127.0.0.1:8081/api/providers", 60*time.Second, func(res *http.Response) error {
|
||||
_, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
}
|
||||
|
|
14
integration/resources/compose/consul_tls.yml
Normal file
14
integration/resources/compose/consul_tls.yml
Normal file
|
@ -0,0 +1,14 @@
|
|||
consul:
|
||||
image: progrium/consul
|
||||
command: -server -bootstrap -log-level debug -ui-dir /ui -config-dir /configs
|
||||
ports:
|
||||
- "8500:8500"
|
||||
- "8585:8585"
|
||||
expose:
|
||||
- "8300"
|
||||
- "8301"
|
||||
- "8301/udp"
|
||||
- "8302"
|
||||
- "8302/udp"
|
||||
volumes:
|
||||
- ../tls:/configs
|
22
integration/resources/tls/ca.cert
Normal file
22
integration/resources/tls/ca.cert
Normal file
|
@ -0,0 +1,22 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDrTCCApWgAwIBAgIJAO8QudN/gvGqMA0GCSqGSIb3DQEBCwUAMG0xCzAJBgNV
|
||||
BAYTAkZSMQ8wDQYDVQQIDAZGcmFuY2UxDTALBgNVBAcMBEx5b24xDzANBgNVBAoM
|
||||
BlplbmlrYTENMAsGA1UEAwwEdGVzdDEeMBwGCSqGSIb3DQEJARYPdGVzdEB6ZW5p
|
||||
a2EuY29tMB4XDTE2MDcwNjA5MTA1MloXDTI2MDcwNDA5MTA1MlowbTELMAkGA1UE
|
||||
BhMCRlIxDzANBgNVBAgMBkZyYW5jZTENMAsGA1UEBwwETHlvbjEPMA0GA1UECgwG
|
||||
WmVuaWthMQ0wCwYDVQQDDAR0ZXN0MR4wHAYJKoZIhvcNAQkBFg90ZXN0QHplbmlr
|
||||
YS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKwrXlde3J8hFY
|
||||
hEvH1GH5SfA64/yb7pjXOwI3kvdS2dkbLglOL/jsolARAfFWxhhnnyJUy/BBzZtS
|
||||
rZN/IukuLCypzjnF6I9koVwILU2EkhPcBUzPZWD6gDU42XZH/lgglZyTyLA/pi24
|
||||
eAag5xVuTBMmBGbRsJJEq8MYgzSOAQLu2K8vFPARZdnvOMXVpfrC5+RxDj1AzyxU
|
||||
5s7olWWG13cWkkh2PUNdb1gCXsz34ALG3EmD2S92tovkKHUZS5zHnOvFl8bF7bKC
|
||||
MoXBi4bL2cUQXq815uFl0gfRrBgN4U+uT2UjzhIV9ax/xnkGueXi9wGPYP3Yanu8
|
||||
dguEtevRAgMBAAGjUDBOMB0GA1UdDgQWBBSxdmZrC6APPhMg73JGRa1sKPB2CDAf
|
||||
BgNVHSMEGDAWgBSxdmZrC6APPhMg73JGRa1sKPB2CDAMBgNVHRMEBTADAQH/MA0G
|
||||
CSqGSIb3DQEBCwUAA4IBAQBEZNfJxlKr/hv/cyfbJX6yUKDRG/sIFVD4G9uNEKak
|
||||
N9Dm5/FZ3pzosq/mBuMjXyY/5kYfiBPpyJfUK7CpWfa/U1RP76dDPm+3aaTNK0XS
|
||||
rWWxP/n5plfb6bt53cfKrnk9ud9ZqY6jX0vQzbVp6F4+jN3ZZfl4SEwlbK0jnrYV
|
||||
pbjPKbDS5o0RNgLuk/KN9x/KLb9FdgTYxVrB4orDUzpxx54sjfHRGodUAO9VIlbZ
|
||||
WteavUhCqbVWvYBB64vxKY695PeX79nmwCMVmsy8luquJYgIn27Czexuei3+2mxX
|
||||
f1rPZL+iCzi8cuShXqhrxH2dNyxsmYFjiPwFHSVgYtL2
|
||||
-----END CERTIFICATE-----
|
19
integration/resources/tls/consul.cert
Normal file
19
integration/resources/tls/consul.cert
Normal file
|
@ -0,0 +1,19 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDBDCCAeygAwIBAgIBEDANBgkqhkiG9w0BAQUFADBtMQswCQYDVQQGEwJGUjEP
|
||||
MA0GA1UECAwGRnJhbmNlMQ0wCwYDVQQHDARMeW9uMQ8wDQYDVQQKDAZaZW5pa2Ex
|
||||
DTALBgNVBAMMBHRlc3QxHjAcBgkqhkiG9w0BCQEWD3Rlc3RAemVuaWthLmNvbTAe
|
||||
Fw0xNjA3MDYxMzMzMTJaFw0yNjA3MDQxMzMzMTJaMBQxEjAQBgNVBAMMCWxvY2Fs
|
||||
aG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyOvmLF7FLDur27bX7OYo
|
||||
lh3RF/9Bo0Eq1+uFbqs7/KNVp66njn4QYT+OLcRTovoCIbTqaFT7jeqIKxpJ+DWL
|
||||
n61BENZvsfSPkxTyF/zekarMHhvrMSpPqEP+NFnfmEVQ4kUELAyREmq6qkZloavV
|
||||
8X8obRjGbNGuWpNLAlO0g68CAwEAAaOBizCBiDAJBgNVHRMEAjAAMB0GA1UdDgQW
|
||||
BBQPlr+xQCpVYfksoxb+tsnNkL63EjAfBgNVHSMEGDAWgBSxdmZrC6APPhMg73JG
|
||||
Ra1sKPB2CDALBgNVHQ8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUF
|
||||
BwMCMA8GA1UdEQQIMAaHBH8AAAEwDQYJKoZIhvcNAQEFBQADggEBAEUgwhGh48yJ
|
||||
JDlR7lT+uWQkPGXuXuATYKOt2fnqYFQ3z3jzP2Og8mR/iZJm85GvsN7CyfVi8hZL
|
||||
sNJOJ1KPRrGVrOFGD4fd8e1sYYw1wowyEiBQii9f/BGy8khw7rl5RrZotuffTulx
|
||||
PWXF9EyO+vLhpkPzCXG7CkJdakWfJX/83C7xfC+wOpyeGG89IW2l4W6yofLV88hL
|
||||
LqBLfuL3J9ZknplSmHDB4W4TFr9aHd2zXdgAUgGd+b0+JfxZtxClivn8RoIkR6Dr
|
||||
JKhxFO9i714+0MKQMEWAvAFcTw8I9ddkQ4cWs9YoYKYdF/cxowAxGYuykI+H92PO
|
||||
ABAA2aH8ilE=
|
||||
-----END CERTIFICATE-----
|
16
integration/resources/tls/consul.key
Normal file
16
integration/resources/tls/consul.key
Normal file
|
@ -0,0 +1,16 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMjr5ixexSw7q9u2
|
||||
1+zmKJYd0Rf/QaNBKtfrhW6rO/yjVaeup45+EGE/ji3EU6L6AiG06mhU+43qiCsa
|
||||
Sfg1i5+tQRDWb7H0j5MU8hf83pGqzB4b6zEqT6hD/jRZ35hFUOJFBCwMkRJquqpG
|
||||
ZaGr1fF/KG0YxmzRrlqTSwJTtIOvAgMBAAECgYB2kymK4/8vRKP/DeBOkeI//abJ
|
||||
p73/79SuCvP7RRko1ugVBrEiGenmypBJGEVXuH4LkG6KViUDMvdboK8oycj0zL6y
|
||||
4naKuWct6EOcxSLhdFyCFLPY+0ggl3F9oG92D02H/3oU7ORBNFBaigSYRSP8EieT
|
||||
5LxCkM2L1cElMJ/6cQJBAP901eNQZSvikAPma+9oPySD01e9yr0AE06wBxGNMkHH
|
||||
OS07WknvIdJAMDKng5Umbp4EG/3UbV5ED/y3NoO22YkCQQDJWVrP5nEx53EXCENb
|
||||
LWDA7SBxjBX60pqvuguDZSjsONQJUlMlqebZSzf/ezLGRUhkzRek8uOwz8MGKnTV
|
||||
sf13AkAGvE3ncHc6cP7bG3g9F8KSc+deqOJvmVDpAjste0uX8GjRiH8Y8/UwVgDv
|
||||
VPtjM2A3SmRyjOdVVPYW8728O1YBAkEAl4aPOPYLKasrCFJHnk5ACfBqAgmSYPgt
|
||||
QSGZmICAk4UQzRMPT8DU4aIhujpUs7FgEbvml1PS1jUEZ5d75XXVcQJAZI50y14r
|
||||
LJ4H+Q2NvvmeyuI8csX+63IGGd/Zt9/EYj4TQnKISnTV3cr/vkmsdoCevC4dT8rS
|
||||
0d1rqCvfNzBUPA==
|
||||
-----END PRIVATE KEY-----
|
9
integration/resources/tls/consul_config.json
Normal file
9
integration/resources/tls/consul_config.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ports": {
|
||||
"https": 8585
|
||||
},
|
||||
"ca_file": "/configs/ca.cert",
|
||||
"cert_file": "/configs/consul.cert",
|
||||
"key_file": "/configs/consul.key",
|
||||
"verify_outgoing": true
|
||||
}
|
42
traefik.go
42
traefik.go
|
@ -22,6 +22,7 @@ import (
|
|||
"runtime"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
var versionTemplate = `Version: {{.Version}}
|
||||
|
@ -118,22 +119,40 @@ Complete documentation is available at https://traefik.io`,
|
|||
|
||||
var kv *staert.KvSource
|
||||
var err error
|
||||
storeConfig := &store.Config{
|
||||
ConnectionTimeout: 30 * time.Second,
|
||||
Bucket: "traefik",
|
||||
}
|
||||
if traefikConfiguration.Consul != nil {
|
||||
//init KvSource
|
||||
if traefikConfiguration.Consul.TLS != nil {
|
||||
storeConfig.TLS, err = traefikConfiguration.Consul.TLS.CreateTLSConfig()
|
||||
if err != nil {
|
||||
fmtlog.Println(err)
|
||||
os.Exit(-1)
|
||||
}
|
||||
}
|
||||
consul.Register()
|
||||
kv, err = staert.NewKvSource(
|
||||
store.CONSUL,
|
||||
strings.Split(traefikConfiguration.Consul.Endpoint, ","),
|
||||
nil,
|
||||
strings.TrimPrefix(traefikConfiguration.Consul.Prefix, "/"), // TrimPrefix should be done in https://github.com/docker/libkv/blob/master/store/consul/consul.go#L113 : IDK why it doen't work
|
||||
storeConfig,
|
||||
strings.TrimPrefix(traefikConfiguration.Consul.Prefix, "/"),
|
||||
)
|
||||
} else if traefikConfiguration.Etcd != nil {
|
||||
//init KvSource
|
||||
if traefikConfiguration.Etcd.TLS != nil {
|
||||
storeConfig.TLS, err = traefikConfiguration.Etcd.TLS.CreateTLSConfig()
|
||||
if err != nil {
|
||||
fmtlog.Println(err)
|
||||
os.Exit(-1)
|
||||
}
|
||||
}
|
||||
etcd.Register()
|
||||
kv, err = staert.NewKvSource(
|
||||
store.ETCD,
|
||||
strings.Split(traefikConfiguration.Etcd.Endpoint, ","),
|
||||
nil,
|
||||
storeConfig,
|
||||
traefikConfiguration.Etcd.Prefix,
|
||||
)
|
||||
} else if traefikConfiguration.Zookeeper != nil {
|
||||
|
@ -160,25 +179,10 @@ Complete documentation is available at https://traefik.io`,
|
|||
os.Exit(-1)
|
||||
}
|
||||
|
||||
// TO DELETE : Used once to fill the kv store
|
||||
// if kv != nil {
|
||||
// fmtlog.Println("Try to store global configuration in consul store")
|
||||
// if err := kv.StoreConfig(traefikConfiguration); err != nil {
|
||||
// fmtlog.Println(fmt.Errorf("Error : %s", err))
|
||||
// os.Exit(-1)
|
||||
// } else {
|
||||
// fmtlog.Println("It seems okay :)")
|
||||
// jsonConf, _ := json.Marshal(traefikConfiguration)
|
||||
// fmtlog.Printf("Global configuration loaded %s", string(jsonConf))
|
||||
// os.Exit(0)
|
||||
// }
|
||||
// }
|
||||
|
||||
//TODO : log warning if many KvStore or set priority
|
||||
if kv != nil {
|
||||
s.AddSource(kv)
|
||||
if _, err := s.LoadConfig(); err != nil {
|
||||
fmtlog.Println(fmt.Errorf("Error : %s", err))
|
||||
fmtlog.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue