diff --git a/integration/etcd3_test.go b/integration/etcd3_test.go index 48645ac4a..df03bab12 100644 --- a/integration/etcd3_test.go +++ b/integration/etcd3_test.go @@ -573,6 +573,113 @@ func (s *Etcd3Suite) TestSNIDynamicTlsConfig(c *check.C) { req.Header.Set("Host", tr2.TLSClientConfig.ServerName) req.Header.Set("Accept", "*/*") resp, err = client.Do(req) + c.Assert(err, checker.IsNil) cn = resp.TLS.PeerCertificates[0].Subject.CommonName c.Assert(cn, checker.Equals, "snitest.org") } + +func (s *Etcd3Suite) TestDeleteSNIDynamicTlsConfig(c *check.C) { + // start Træfik + cmd, display := s.traefikCmd( + withConfigFile("fixtures/etcd/simple_https.toml"), + "--etcd", + "--etcd.endpoint="+ipEtcd+":4001", + "--etcd.useAPIV3=true") + defer display(c) + + // prepare to config + snitestComCert, err := ioutil.ReadFile("fixtures/https/snitest.com.cert") + c.Assert(err, checker.IsNil) + snitestComKey, err := ioutil.ReadFile("fixtures/https/snitest.com.key") + c.Assert(err, checker.IsNil) + + backend1 := map[string]string{ + "/traefik/backends/backend1/circuitbreaker/expression": "NetworkErrorRatio() > 0.5", + "/traefik/backends/backend1/servers/server1/url": "http://" + ipWhoami01 + ":80", + "/traefik/backends/backend1/servers/server1/weight": "1", + "/traefik/backends/backend1/servers/server2/url": "http://" + ipWhoami02 + ":80", + "/traefik/backends/backend1/servers/server2/weight": "1", + } + + frontend1 := map[string]string{ + "/traefik/frontends/frontend1/backend": "backend1", + "/traefik/frontends/frontend1/entrypoints": "https", + "/traefik/frontends/frontend1/priority": "1", + "/traefik/frontends/frontend1/routes/test_1/rule": "Host:snitest.com", + } + + tlsconfigure1 := map[string]string{ + "/traefik/tlsconfiguration/snitestcom/entrypoints": "https", + "/traefik/tlsconfiguration/snitestcom/certificate/keyfile": string(snitestComKey), + "/traefik/tlsconfiguration/snitestcom/certificate/certfile": string(snitestComCert), + } + + // config backends,frontends and first tls keypair + for key, value := range backend1 { + err := s.kv.Put(key, []byte(value), nil) + c.Assert(err, checker.IsNil) + } + for key, value := range frontend1 { + err := s.kv.Put(key, []byte(value), nil) + c.Assert(err, checker.IsNil) + } + for key, value := range tlsconfigure1 { + err := s.kv.Put(key, []byte(value), nil) + c.Assert(err, checker.IsNil) + } + + tr1 := &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + ServerName: "snitest.com", + }, + } + + // wait for etcd + err = try.Do(60*time.Second, func() error { + _, err := s.kv.Get("/traefik/tlsconfiguration/snitestcom/certificate/keyfile", nil) + return err + }) + c.Assert(err, checker.IsNil) + + err = cmd.Start() + c.Assert(err, checker.IsNil) + defer cmd.Process.Kill() + + // wait for Træfik + err = try.GetRequest(traefikWebEtcdURL+"api/providers", 60*time.Second, try.BodyContains(string("MIIEpQIBAAKCAQEA1RducBK6EiFDv3TYB8ZcrfKWRVaSfHzWicO3J5WdST9oS7h"))) + c.Assert(err, checker.IsNil) + + req, err := http.NewRequest(http.MethodGet, "https://127.0.0.1:4443/", nil) + c.Assert(err, checker.IsNil) + client := &http.Client{Transport: tr1} + req.Host = tr1.TLSClientConfig.ServerName + req.Header.Set("Host", tr1.TLSClientConfig.ServerName) + req.Header.Set("Accept", "*/*") + var resp *http.Response + resp, err = client.Do(req) + c.Assert(err, checker.IsNil) + cn := resp.TLS.PeerCertificates[0].Subject.CommonName + c.Assert(cn, checker.Equals, "snitest.com") + + // now we delete the tls cert/key pairs,so the endpoint show use default cert/key pair + for key := range tlsconfigure1 { + err := s.kv.Delete(key) + c.Assert(err, checker.IsNil) + } + + // waiting for Træfik to pull configuration + err = try.GetRequest(traefikWebEtcdURL+"api/providers", 30*time.Second, try.BodyNotContains("MIIEpQIBAAKCAQEA1RducBK6EiFDv3TYB8ZcrfKWRVaSfHzWicO3J5WdST9oS7h")) + c.Assert(err, checker.IsNil) + + req, err = http.NewRequest(http.MethodGet, "https://127.0.0.1:4443/", nil) + c.Assert(err, checker.IsNil) + client = &http.Client{Transport: tr1} + req.Host = tr1.TLSClientConfig.ServerName + req.Header.Set("Host", tr1.TLSClientConfig.ServerName) + req.Header.Set("Accept", "*/*") + resp, err = client.Do(req) + c.Assert(err, checker.IsNil) + cn = resp.TLS.PeerCertificates[0].Subject.CommonName + c.Assert(cn, checker.Equals, "TRAEFIK DEFAULT CERT") +} diff --git a/integration/try/condition.go b/integration/try/condition.go index bff63b0cb..93010631f 100644 --- a/integration/try/condition.go +++ b/integration/try/condition.go @@ -34,6 +34,25 @@ func BodyContains(values ...string) ResponseCondition { } } +// BodyNotContains returns a retry condition function. +// The condition returns an error if the request body contain one of the given +// strings. +func BodyNotContains(values ...string) ResponseCondition { + return func(res *http.Response) error { + body, err := ioutil.ReadAll(res.Body) + if err != nil { + return fmt.Errorf("failed to read response body: %s", err) + } + + for _, value := range values { + if strings.Contains(string(body), value) { + return fmt.Errorf("find '%s' in body '%s'", value, string(body)) + } + } + return nil + } +} + // BodyContainsOr returns a retry condition function. // The condition returns an error if the request body does not contain one of the given // strings.