Compare commits

...

45 Commits

Author SHA1 Message Date
Emile Vauge
fe1b982d13 Merge pull request #856 from containous/prepare-release-v1.1.0
Changelog v1.1.0
2016-11-17 22:41:11 +01:00
Emile Vauge
221ae2427b changelog v1.1.0 2016-11-17 22:07:15 +01:00
Emile Vauge
29f780863b Merge pull request #845 from containous/fix-kubernetes-watch-leak
Fix Kubernetes watch leak
2016-11-17 18:54:12 +01:00
Emile Vauge
8aaca8e55c Update docs with errm talk 2016-11-17 17:37:06 +01:00
Emile Vauge
2dda3d2feb Fix Kubernetes watch leak
Signed-off-by: Emile Vauge <emile@vauge.com>
2016-11-17 17:37:06 +01:00
Emile Vauge
22ebaedb45 Merge pull request #855 from containous/fix-path-case-sensitive-v1.1
Fix path case sensitive v1.1
2016-11-17 17:36:40 +01:00
Steven Bower
7065f00443 Fixes #851 (#852) 2016-11-17 15:40:25 +01:00
Emile Vauge
801e0f9ef7 Merge pull request #849 from containous/fix-golint-1.1
Fix golint in v1.1
2016-11-16 12:26:56 +01:00
Ed Robinson
ac20ddfc6c Fix golint
recent additions to golint mean that a number of files cause the
build to start failing if they are edited (we only run against changed
files)

This fixes all the errors in the repo so things don't unexpectedly start
failing for people making PRs
2016-11-16 11:52:15 +01:00
Vincent Demeester
f6576cce27 Merge pull request #842 from guilhem/version-cross-binary
Pass Version, Codename and Date to crosscompiled
2016-11-14 17:35:58 +01:00
Guilhem Lettron
d3b48cdd22 Pass Version, Codename and Date to crosscompiled
Copy variables from ./script/binary
2016-11-14 16:41:30 +01:00
Emile Vauge
c26b36cf4f Merge pull request #820 from trecloux/check_http2
Check that we serve HTTP/2
2016-11-14 09:38:31 +01:00
Thomas Recloux
3095da64d7 Check that we provide HTTP/2 2016-11-14 09:10:47 +01:00
Vincent Demeester
07f961ecba Merge pull request #829 from SantoDE/fix-webui-dashboard
Add Nvd3 Dependency to fix UI / Dashboard
2016-11-13 11:47:22 +01:00
Manuel Laufenberg
3db6e185e0 Add Nvd3 Dependency to fix UI / Dashboard 2016-11-11 21:50:59 +01:00
Emile Vauge
4430befe90 Merge pull request #823 from containous/fix-mkdoc-theme
Fix mkdoc theme
2016-11-10 12:20:46 +01:00
Emile Vauge
1c4eb4322b Fix changelog 2016-11-10 11:15:42 +01:00
Emile Vauge
3f3fa61a51 Fix mkdocs theme 2016-11-10 11:12:54 +01:00
Emile Vauge
ddf24039e8 Merge pull request #822 from containous/prepare-release-v1.1.0-rc4
Prepare release v1.1.0 rc4
2016-11-10 10:40:36 +01:00
Emile Vauge
5b6a5f8aa9 Changelog v1.1.0-rc4 2016-11-09 22:00:10 +01:00
Emile Vauge
3e6d2391f7 Add dtomcej, SantoDE remove samber from maintainers 2016-11-09 21:59:58 +01:00
Emile Vauge
664ee9d82f Merge pull request #814 from containous/fix-acme-renew
Fix multiple issues
2016-11-09 21:47:13 +01:00
Emile Vauge
c9cc3c9895 Fix contraint store/read from KV
Signed-off-by: Emile Vauge <emile@vauge.com>
2016-11-09 21:08:37 +01:00
Emile Vauge
00c7e5c72b Ensure HTTP/2 enabled 2016-11-09 17:56:41 +01:00
Emile Vauge
558b31f4d9 Fix oxy version 2016-11-08 10:34:39 +01:00
Emile Vauge
174a5e7f13 Fix ACME renew 2016-11-07 21:51:23 +01:00
Emile Vauge
c821f191b0 Merge pull request #783 from containous/add-version-check
Fix ACME renew & add version check
2016-11-03 14:14:06 +01:00
Emile Vauge
3322e564fd Add version check
Signed-off-by: Emile Vauge <emile@vauge.com>
2016-11-03 11:30:00 +01:00
Emile Vauge
7bf5d557c1 Fix acme renew 2016-11-03 11:30:00 +01:00
Vincent Demeester
0c1e06199c Merge pull request #782 from guilhem/defaultToIndex1
Use first port by default
2016-11-02 14:34:42 -07:00
Guilhem Lettron
85a20b9a39 Use first index for ports 2016-11-02 17:31:27 +01:00
Guilhem Lettron
5641af437e Use first port by default
If no information is given, use first index of ports
2016-10-28 11:59:24 +02:00
Guilhem Lettron
1c8d3ded3d Add name to some case to help debug 2016-10-28 11:59:24 +02:00
Emile Vauge
c2a445370e Merge pull request #779 from containous/prepare-release-v1.1.0-rc3
Prepare release v1.1.0-rc3
2016-10-26 17:59:09 +02:00
Emile Vauge
8e5355f2d9 Prepare release v1.1.0-rc3
Signed-off-by: Emile Vauge <emile@vauge.com>
2016-10-26 17:38:18 +02:00
Emile Vauge
2492157833 Merge pull request #776 from containous/fix-response-recorder-flush
Fix ResponseRecorder Flush
2016-10-26 17:00:49 +02:00
Emile Vauge
7c375e8fd9 Fix ResponseRecorder Flush
Signed-off-by: Emile Vauge <emile@vauge.com>
2016-10-26 16:26:19 +02:00
Emile Vauge
53b5d8ac33 Merge pull request #758 from containous/fix-multiple-certs-flag
Fix multiple certificates using flag
2016-10-26 16:23:06 +02:00
Emile Vauge
e5a8fb390e Fix multiple certificates using flags
Signed-off-by: Emile Vauge <emile@vauge.com>
2016-10-26 15:40:27 +02:00
Emile Vauge
79cbae0c73 Merge pull request #759 from containous/fix-mapstructure-slice
Fix mapstructure issue with anonymous slice
2016-10-26 15:39:45 +02:00
Emile Vauge
22b0b8b750 Fix mapstructure issue with anonymous slice
Signed-off-by: Emile Vauge <emile@vauge.com>
2016-10-26 15:17:54 +02:00
Emile Vauge
ddbddf6edf Merge pull request #760 from containous/fix-ProvidersThrottleDuration-doc
Fix providers throttle duration doc
2016-10-26 14:20:10 +02:00
Emile Vauge
adcf58da68 Fix ProvidersThrottleDuration doc 2016-10-26 12:47:19 +02:00
Guilhem Lettron
649cb548d0 Use sdnotify for systemd (#768)
* Use sdnotify for systemd

This is useful if a configuration is long to load.
Systemd will continue dependency chain only when server have finish to start.

https://www.freedesktop.org/software/systemd/man/systemd.service.html#Type=

* Extract the waiting behavior from Start()
2016-10-25 08:59:39 -07:00
Vincent Demeester
870f378782 Merge pull request #748 from containous/really-fix-deploy-ghr
Really fix deploy ghr...
2016-10-19 12:14:54 +02:00
43 changed files with 638 additions and 157 deletions

View File

@@ -20,6 +20,7 @@ install:
- docker version
- pip install --user mkdocs
- pip install --user pymdown-extensions
- pip install --user mkdocs-bootswatch
before_script:
- make validate
- make binary

View File

@@ -1,5 +1,268 @@
# Change Log
## [v1.1.0](https://github.com/containous/traefik/tree/v1.1.0) (2016-11-17)
[Full Changelog](https://github.com/containous/traefik/compare/v1.0.0...v1.1.0)
**Implemented enhancements:**
- Support healthcheck if present for docker [\#666](https://github.com/containous/traefik/issues/666)
- Standard unit for traefik latency in access log [\#559](https://github.com/containous/traefik/issues/559)
- \[CI\] wiredep marked as unmaintained [\#550](https://github.com/containous/traefik/issues/550)
- Feature Request: Enable Health checks to containers. [\#540](https://github.com/containous/traefik/issues/540)
- Feature Request: SSL Cipher Selection [\#535](https://github.com/containous/traefik/issues/535)
- Error with -consulcatalog and missing load balance method on 1.0.0 [\#524](https://github.com/containous/traefik/issues/524)
- Running Traefik with Docker 1.12 Swarm Mode [\#504](https://github.com/containous/traefik/issues/504)
- Kubernetes provider: should allow the master url to be override [\#501](https://github.com/containous/traefik/issues/501)
- \[FRONTEND\]\[LE\] Pre-generate SSL certificates for "Host:" rules [\#483](https://github.com/containous/traefik/issues/483)
- Frontend Rule evolution [\#437](https://github.com/containous/traefik/issues/437)
- Add a Changelog [\#388](https://github.com/containous/traefik/issues/388)
- Add label matching for kubernetes ingests [\#363](https://github.com/containous/traefik/issues/363)
- Acme in HA Traefik Scenario [\#348](https://github.com/containous/traefik/issues/348)
- HTTP Basic Auth support [\#77](https://github.com/containous/traefik/issues/77)
- Session affinity / stickiness / persistence [\#5](https://github.com/containous/traefik/issues/5)
**Fixed bugs:**
- 1.1.0-rc4 dashboard UX not displaying [\#828](https://github.com/containous/traefik/issues/828)
- Traefik stopped serving on upgrade to v1.1.0-rc3 [\#807](https://github.com/containous/traefik/issues/807)
- cannot access webui/dashboard [\#796](https://github.com/containous/traefik/issues/796)
- Traefik cannot read constraints from KV [\#794](https://github.com/containous/traefik/issues/794)
- HTTP2 - configuration [\#790](https://github.com/containous/traefik/issues/790)
- Cannot provide multiple certificates using flag [\#757](https://github.com/containous/traefik/issues/757)
- Allow multiple certificates on a single entrypoint when trying to use TLS? [\#747](https://github.com/containous/traefik/issues/747)
- traefik \* Users: unsupported type: slice [\#743](https://github.com/containous/traefik/issues/743)
- \[Docker swarm mode\] The traefik.docker.network seems to have no effect [\#719](https://github.com/containous/traefik/issues/719)
- traefik hangs - stops handling requests [\#662](https://github.com/containous/traefik/issues/662)
- Add long jobs in exponential backoff providers [\#626](https://github.com/containous/traefik/issues/626)
- Tip of tree crashes on invalid pointer on Marathon provider [\#624](https://github.com/containous/traefik/issues/624)
- ACME: revoke certificate on agreement update [\#579](https://github.com/containous/traefik/issues/579)
- WebUI: Providers tabs disappeared [\#577](https://github.com/containous/traefik/issues/577)
- traefik version command contains incorrect information when building from master branch [\#569](https://github.com/containous/traefik/issues/569)
- Case sensitive domain names breaks routing [\#562](https://github.com/containous/traefik/issues/562)
- Flag --etcd.endpoint default [\#508](https://github.com/containous/traefik/issues/508)
- Conditional ACME on demand generation [\#505](https://github.com/containous/traefik/issues/505)
- Important delay with streams \(Mozilla EventSource\) [\#503](https://github.com/containous/traefik/issues/503)
- Traefik crashing [\#458](https://github.com/containous/traefik/issues/458)
- traefik.toml constraints error: `Expected map but found 'string'.` [\#451](https://github.com/containous/traefik/issues/451)
- Multiple path separators in the url path causing redirect [\#167](https://github.com/containous/traefik/issues/167)
**Closed issues:**
- All path rules require paths to be lowercase [\#851](https://github.com/containous/traefik/issues/851)
- The UI stops working after a time and have to restart the service. [\#840](https://github.com/containous/traefik/issues/840)
- Incorrect Dashboard page returned [\#831](https://github.com/containous/traefik/issues/831)
- LoadBalancing doesn't work in single node Swarm-mode [\#815](https://github.com/containous/traefik/issues/815)
- cannot connect to docker daemon [\#813](https://github.com/containous/traefik/issues/813)
- Let's encrypt configuration not working [\#805](https://github.com/containous/traefik/issues/805)
- Multiple subdomains for Marathon backend. [\#785](https://github.com/containous/traefik/issues/785)
- traefik-1.1.0-rc1: build error [\#781](https://github.com/containous/traefik/issues/781)
- dependencies installation error [\#755](https://github.com/containous/traefik/issues/755)
- k8s provider w/ acme? [\#752](https://github.com/containous/traefik/issues/752)
- Swarm Docs - How to use a FQDN [\#744](https://github.com/containous/traefik/issues/744)
- Documented ProvidersThrottleDuration value is invalid [\#741](https://github.com/containous/traefik/issues/741)
- Sensible configuration for consulCatalog [\#737](https://github.com/containous/traefik/issues/737)
- Traefik ignoring container listening in more than one TCP port [\#734](https://github.com/containous/traefik/issues/734)
- Loadbalaning issues with traefik and Docker Swarm cluster [\#730](https://github.com/containous/traefik/issues/730)
- issues with marathon app ids containing a dot [\#726](https://github.com/containous/traefik/issues/726)
- Error when using HA acme in kubernetes with etcd [\#725](https://github.com/containous/traefik/issues/725)
- \[Docker swarm mode\] No round robin when using service [\#718](https://github.com/containous/traefik/issues/718)
- Dose it support docker swarm mode [\#712](https://github.com/containous/traefik/issues/712)
- Kubernetes - Undefined backend [\#710](https://github.com/containous/traefik/issues/710)
- How Routing traffic depending on path not domain in docker [\#706](https://github.com/containous/traefik/issues/706)
- Constraints on Consul Catalogue not working as expected [\#703](https://github.com/containous/traefik/issues/703)
- Global InsecureSkipVerify does not work [\#700](https://github.com/containous/traefik/issues/700)
- Traefik crashes when using Consul catalog [\#699](https://github.com/containous/traefik/issues/699)
- \[documentation/feature\] Consul/etcd support atomic multiple key changes now [\#698](https://github.com/containous/traefik/issues/698)
- How to configure which network to use when starting traefik binary? [\#694](https://github.com/containous/traefik/issues/694)
- How to get multiple host headers working for docker labels? [\#692](https://github.com/containous/traefik/issues/692)
- Requests with URL-encoded characters are not forwarded correctly [\#684](https://github.com/containous/traefik/issues/684)
- File Watcher for rules does not work [\#683](https://github.com/containous/traefik/issues/683)
- Issue with global InsecureSkipVerify = true and self signed certificates [\#667](https://github.com/containous/traefik/issues/667)
- Docker exposedbydefault = false didn't work [\#663](https://github.com/containous/traefik/issues/663)
- swarm documentation needs update [\#656](https://github.com/containous/traefik/issues/656)
- \[ACME\] Auto SAN Detection [\#655](https://github.com/containous/traefik/issues/655)
- Fronting a domain with DNS A-record round-robin & ACME [\#654](https://github.com/containous/traefik/issues/654)
- Overriding toml configuration with environment variables [\#650](https://github.com/containous/traefik/issues/650)
- marathon provider exposedByDefault = false [\#647](https://github.com/containous/traefik/issues/647)
- Add status URL for service up checks [\#642](https://github.com/containous/traefik/issues/642)
- acme's storage file, containing private key, is word readable [\#638](https://github.com/containous/traefik/issues/638)
- wildcard domain with exclusions [\#633](https://github.com/containous/traefik/issues/633)
- Enable evenly distribution among backend [\#631](https://github.com/containous/traefik/issues/631)
- Traefik sporadically failing when proxying requests [\#615](https://github.com/containous/traefik/issues/615)
- TCP Proxy [\#608](https://github.com/containous/traefik/issues/608)
- How to use in Windows? [\#605](https://github.com/containous/traefik/issues/605)
- `ClientCAFiles` ignored [\#604](https://github.com/containous/traefik/issues/604)
- Let`s Encrypt enable in etcd [\#600](https://github.com/containous/traefik/issues/600)
- Support HTTP Basic Auth [\#599](https://github.com/containous/traefik/issues/599)
- Consul KV seem broken [\#587](https://github.com/containous/traefik/issues/587)
- HTTPS entryPoint not working [\#574](https://github.com/containous/traefik/issues/574)
- Traefik stuck when used as frontend for a streaming API [\#560](https://github.com/containous/traefik/issues/560)
- Exclude some frontends in consul catalog [\#555](https://github.com/containous/traefik/issues/555)
- Update docs with new Mesos provider [\#548](https://github.com/containous/traefik/issues/548)
- Can I use Traefik without a domain name? [\#539](https://github.com/containous/traefik/issues/539)
- docker run syntax in swarm example has changed [\#528](https://github.com/containous/traefik/issues/528)
- Priortities in 1.0.0 not behaving [\#506](https://github.com/containous/traefik/issues/506)
- Route by path [\#500](https://github.com/containous/traefik/issues/500)
- Secure WebSockets [\#467](https://github.com/containous/traefik/issues/467)
- Container IP Lost [\#375](https://github.com/containous/traefik/issues/375)
- Multiple routes support with Docker or Marathon labels [\#118](https://github.com/containous/traefik/issues/118)
**Merged pull requests:**
- Fix path case sensitive v1.1 [\#855](https://github.com/containous/traefik/pull/855) ([emilevauge](https://github.com/emilevauge))
- Fix golint in v1.1 [\#849](https://github.com/containous/traefik/pull/849) ([emilevauge](https://github.com/emilevauge))
- Fix Kubernetes watch leak [\#845](https://github.com/containous/traefik/pull/845) ([emilevauge](https://github.com/emilevauge))
- Pass Version, Codename and Date to crosscompiled [\#842](https://github.com/containous/traefik/pull/842) ([guilhem](https://github.com/guilhem))
- Add Nvd3 Dependency to fix UI / Dashboard [\#829](https://github.com/containous/traefik/pull/829) ([SantoDE](https://github.com/SantoDE))
- Fix mkdoc theme [\#823](https://github.com/containous/traefik/pull/823) ([emilevauge](https://github.com/emilevauge))
- Prepare release v1.1.0 rc4 [\#822](https://github.com/containous/traefik/pull/822) ([emilevauge](https://github.com/emilevauge))
- Check that we serve HTTP/2 [\#820](https://github.com/containous/traefik/pull/820) ([trecloux](https://github.com/trecloux))
- Fix multiple issues [\#814](https://github.com/containous/traefik/pull/814) ([emilevauge](https://github.com/emilevauge))
- Fix ACME renew & add version check [\#783](https://github.com/containous/traefik/pull/783) ([emilevauge](https://github.com/emilevauge))
- Use first port by default [\#782](https://github.com/containous/traefik/pull/782) ([guilhem](https://github.com/guilhem))
- Prepare release v1.1.0-rc3 [\#779](https://github.com/containous/traefik/pull/779) ([emilevauge](https://github.com/emilevauge))
- Fix ResponseRecorder Flush [\#776](https://github.com/containous/traefik/pull/776) ([emilevauge](https://github.com/emilevauge))
- Use sdnotify for systemd [\#768](https://github.com/containous/traefik/pull/768) ([guilhem](https://github.com/guilhem))
- Fix providers throttle duration doc [\#760](https://github.com/containous/traefik/pull/760) ([emilevauge](https://github.com/emilevauge))
- Fix mapstructure issue with anonymous slice [\#759](https://github.com/containous/traefik/pull/759) ([emilevauge](https://github.com/emilevauge))
- Fix multiple certificates using flag [\#758](https://github.com/containous/traefik/pull/758) ([emilevauge](https://github.com/emilevauge))
- Really fix deploy ghr... [\#748](https://github.com/containous/traefik/pull/748) ([emilevauge](https://github.com/emilevauge))
- Fixes deploy ghr [\#742](https://github.com/containous/traefik/pull/742) ([emilevauge](https://github.com/emilevauge))
- prepare v1.1.0-rc2 [\#740](https://github.com/containous/traefik/pull/740) ([emilevauge](https://github.com/emilevauge))
- Fix case sensitive host [\#733](https://github.com/containous/traefik/pull/733) ([emilevauge](https://github.com/emilevauge))
- Update Kubernetes examples [\#731](https://github.com/containous/traefik/pull/731) ([Starefossen](https://github.com/Starefossen))
- fIx marathon template with dots in ID [\#728](https://github.com/containous/traefik/pull/728) ([emilevauge](https://github.com/emilevauge))
- Fix networkMap construction in ListServices [\#724](https://github.com/containous/traefik/pull/724) ([vincentlepot](https://github.com/vincentlepot))
- Add basic compatibility with marathon-lb [\#720](https://github.com/containous/traefik/pull/720) ([guilhem](https://github.com/guilhem))
- Add Ed's video at ContainerCamp [\#717](https://github.com/containous/traefik/pull/717) ([emilevauge](https://github.com/emilevauge))
- Add documentation for Træfik on docker swarm mode [\#715](https://github.com/containous/traefik/pull/715) ([vdemeester](https://github.com/vdemeester))
- Remove duplicated link to Kubernetes.io in README.md [\#713](https://github.com/containous/traefik/pull/713) ([oscerd](https://github.com/oscerd))
- Show current version in web UI [\#709](https://github.com/containous/traefik/pull/709) ([vhf](https://github.com/vhf))
- Add support for docker healthcheck 👼 [\#708](https://github.com/containous/traefik/pull/708) ([vdemeester](https://github.com/vdemeester))
- Fix syntax in Swarm example. Resolves \#528 [\#707](https://github.com/containous/traefik/pull/707) ([billglover](https://github.com/billglover))
- Add HTTP compression [\#702](https://github.com/containous/traefik/pull/702) ([tuier](https://github.com/tuier))
- Carry PR 446 - Add sticky session support \(round two!\) [\#701](https://github.com/containous/traefik/pull/701) ([emilevauge](https://github.com/emilevauge))
- Remove unused endpoint when using constraints with Marathon provider [\#697](https://github.com/containous/traefik/pull/697) ([tuier](https://github.com/tuier))
- Replace imagelayers.io with microbadger [\#696](https://github.com/containous/traefik/pull/696) ([solidnerd](https://github.com/solidnerd))
- Selectable TLS Versions [\#690](https://github.com/containous/traefik/pull/690) ([dtomcej](https://github.com/dtomcej))
- Carry pr 439 [\#689](https://github.com/containous/traefik/pull/689) ([emilevauge](https://github.com/emilevauge))
- Disable gorilla/mux URL cleaning to prevent sending redirect [\#688](https://github.com/containous/traefik/pull/688) ([ydubreuil](https://github.com/ydubreuil))
- Some fixes [\#687](https://github.com/containous/traefik/pull/687) ([emilevauge](https://github.com/emilevauge))
- feat\(constraints\): Supports constraints for Marathon provider [\#686](https://github.com/containous/traefik/pull/686) ([tuier](https://github.com/tuier))
- Update docs to improve contribution setup [\#685](https://github.com/containous/traefik/pull/685) ([dtomcej](https://github.com/dtomcej))
- Add basic auth support for web backend [\#677](https://github.com/containous/traefik/pull/677) ([SantoDE](https://github.com/SantoDE))
- Document accepted values for logLevel. [\#676](https://github.com/containous/traefik/pull/676) ([jimmycuadra](https://github.com/jimmycuadra))
- If Marathon doesn't have healthcheck, assume it's ok [\#665](https://github.com/containous/traefik/pull/665) ([gomes](https://github.com/gomes))
- ACME: renew certificates 30 days before expiry [\#660](https://github.com/containous/traefik/pull/660) ([JayH5](https://github.com/JayH5))
- Update broken link and add a comment to sample config file [\#658](https://github.com/containous/traefik/pull/658) ([Yggdrasil](https://github.com/Yggdrasil))
- Add possibility to use BindPort IPAddress 👼 [\#657](https://github.com/containous/traefik/pull/657) ([vdemeester](https://github.com/vdemeester))
- Update marathon [\#648](https://github.com/containous/traefik/pull/648) ([emilevauge](https://github.com/emilevauge))
- Add backend features to docker [\#646](https://github.com/containous/traefik/pull/646) ([jangie](https://github.com/jangie))
- enable consul catalog to use maxconn [\#645](https://github.com/containous/traefik/pull/645) ([jangie](https://github.com/jangie))
- Adopt the Code Of Coduct from http://contributor-covenant.org [\#641](https://github.com/containous/traefik/pull/641) ([errm](https://github.com/errm))
- Use secure mode 600 instead of 644 for acme.json [\#639](https://github.com/containous/traefik/pull/639) ([discordianfish](https://github.com/discordianfish))
- docker clarification, fix dead urls, misc typos [\#637](https://github.com/containous/traefik/pull/637) ([djalal](https://github.com/djalal))
- add PING handler to dashboard API [\#630](https://github.com/containous/traefik/pull/630) ([jangie](https://github.com/jangie))
- Migrate to JobBackOff [\#628](https://github.com/containous/traefik/pull/628) ([emilevauge](https://github.com/emilevauge))
- Add long job exponential backoff [\#627](https://github.com/containous/traefik/pull/627) ([emilevauge](https://github.com/emilevauge))
- HA acme support [\#625](https://github.com/containous/traefik/pull/625) ([emilevauge](https://github.com/emilevauge))
- Bump go v1.7 [\#620](https://github.com/containous/traefik/pull/620) ([emilevauge](https://github.com/emilevauge))
- Make duration logging consistent [\#619](https://github.com/containous/traefik/pull/619) ([jangie](https://github.com/jangie))
- fix for nil clientTLS causing issue [\#617](https://github.com/containous/traefik/pull/617) ([jangie](https://github.com/jangie))
- Add ability for marathon provider to set maxconn values, loadbalancer algorithm, and circuit breaker expression [\#616](https://github.com/containous/traefik/pull/616) ([jangie](https://github.com/jangie))
- Make systemd unit installable [\#613](https://github.com/containous/traefik/pull/613) ([keis](https://github.com/keis))
- Merge v1.0.2 master [\#610](https://github.com/containous/traefik/pull/610) ([emilevauge](https://github.com/emilevauge))
- update staert and flaeg [\#609](https://github.com/containous/traefik/pull/609) ([cocap10](https://github.com/cocap10))
- \#504 Initial support for Docker 1.12 Swarm Mode [\#602](https://github.com/containous/traefik/pull/602) ([diegofernandes](https://github.com/diegofernandes))
- Add Host cert ACME generation [\#601](https://github.com/containous/traefik/pull/601) ([emilevauge](https://github.com/emilevauge))
- Fixed binary script so traefik version command doesn't just print default values [\#598](https://github.com/containous/traefik/pull/598) ([keiths-osc](https://github.com/keiths-osc))
- Name servers after thier pods [\#596](https://github.com/containous/traefik/pull/596) ([errm](https://github.com/errm))
- Fix Consul prefix [\#589](https://github.com/containous/traefik/pull/589) ([jippi](https://github.com/jippi))
- Prioritize kubernetes routes by path length [\#588](https://github.com/containous/traefik/pull/588) ([philk](https://github.com/philk))
- beautify help [\#580](https://github.com/containous/traefik/pull/580) ([cocap10](https://github.com/cocap10))
- Upgrade directives name since we use angular-ui-bootstrap [\#578](https://github.com/containous/traefik/pull/578) ([micaelmbagira](https://github.com/micaelmbagira))
- Fix basic docs for configuration of multiple rules [\#576](https://github.com/containous/traefik/pull/576) ([ajaegle](https://github.com/ajaegle))
- Fix k8s watch [\#573](https://github.com/containous/traefik/pull/573) ([errm](https://github.com/errm))
- Add requirements.txt for netlify [\#567](https://github.com/containous/traefik/pull/567) ([emilevauge](https://github.com/emilevauge))
- Merge v1.0.1 master [\#565](https://github.com/containous/traefik/pull/565) ([emilevauge](https://github.com/emilevauge))
- Move webui to FountainJS with Webpack [\#558](https://github.com/containous/traefik/pull/558) ([micaelmbagira](https://github.com/micaelmbagira))
- Add global InsecureSkipVerify option to disable certificate checking [\#557](https://github.com/containous/traefik/pull/557) ([stuart-c](https://github.com/stuart-c))
- Move version.go in its own package… [\#553](https://github.com/containous/traefik/pull/553) ([vdemeester](https://github.com/vdemeester))
- Upgrade libkermit and dependencies [\#552](https://github.com/containous/traefik/pull/552) ([vdemeester](https://github.com/vdemeester))
- Add command storeconfig [\#551](https://github.com/containous/traefik/pull/551) ([cocap10](https://github.com/cocap10))
- Add basic/digest auth [\#547](https://github.com/containous/traefik/pull/547) ([emilevauge](https://github.com/emilevauge))
- Bump node to 6 for webui [\#546](https://github.com/containous/traefik/pull/546) ([vdemeester](https://github.com/vdemeester))
- Bump golang to 1.6.3 [\#545](https://github.com/containous/traefik/pull/545) ([vdemeester](https://github.com/vdemeester))
- Fix typos [\#538](https://github.com/containous/traefik/pull/538) ([jimt](https://github.com/jimt))
- Kubernetes user-guide [\#519](https://github.com/containous/traefik/pull/519) ([errm](https://github.com/errm))
- Implement Kubernetes Selectors, minor kube endpoint fix [\#516](https://github.com/containous/traefik/pull/516) ([pnegahdar](https://github.com/pnegahdar))
- Carry \#358 : Option to disable expose of all docker containers [\#514](https://github.com/containous/traefik/pull/514) ([vdemeester](https://github.com/vdemeester))
- Remove traefik.frontend.value support in docker… [\#510](https://github.com/containous/traefik/pull/510) ([vdemeester](https://github.com/vdemeester))
- Use KvStores as global config sources [\#481](https://github.com/containous/traefik/pull/481) ([cocap10](https://github.com/cocap10))
- Add endpoint option to authenticate by client tls cert. [\#461](https://github.com/containous/traefik/pull/461) ([andersbetner](https://github.com/andersbetner))
- add mesos provider inspired by mesos-dns & marathon provider [\#353](https://github.com/containous/traefik/pull/353) ([skydjol](https://github.com/skydjol))
## [v1.1.0-rc4](https://github.com/containous/traefik/tree/v1.1.0-rc4) (2016-11-10)
[Full Changelog](https://github.com/containous/traefik/compare/v1.1.0-rc3...v1.1.0-rc4)
**Implemented enhancements:**
- Feature Request: Enable Health checks to containers. [\#540](https://github.com/containous/traefik/issues/540)
**Fixed bugs:**
- Traefik stopped serving on upgrade to v1.1.0-rc3 [\#807](https://github.com/containous/traefik/issues/807)
- Traefik cannot read constraints from KV [\#794](https://github.com/containous/traefik/issues/794)
- HTTP2 - configuration [\#790](https://github.com/containous/traefik/issues/790)
- Allow multiple certificates on a single entrypoint when trying to use TLS? [\#747](https://github.com/containous/traefik/issues/747)
**Closed issues:**
- LoadBalancing doesn't work in single node Swarm-mode [\#815](https://github.com/containous/traefik/issues/815)
- cannot connect to docker daemon [\#813](https://github.com/containous/traefik/issues/813)
- Let's encrypt configuration not working [\#805](https://github.com/containous/traefik/issues/805)
- Question: Wildcard Host for Kubernetes Ingress [\#792](https://github.com/containous/traefik/issues/792)
- Multiple subdomains for Marathon backend. [\#785](https://github.com/containous/traefik/issues/785)
- traefik-1.1.0-rc1: build error [\#781](https://github.com/containous/traefik/issues/781)
- Multiple routes support with Docker or Marathon labels [\#118](https://github.com/containous/traefik/issues/118)
**Merged pull requests:**
- Prepare release v1.1.0 rc4 [\#822](https://github.com/containous/traefik/pull/822) ([emilevauge](https://github.com/emilevauge))
- Fix multiple issues [\#814](https://github.com/containous/traefik/pull/814) ([emilevauge](https://github.com/emilevauge))
- Fix ACME renew & add version check [\#783](https://github.com/containous/traefik/pull/783) ([emilevauge](https://github.com/emilevauge))
- Use first port by default [\#782](https://github.com/containous/traefik/pull/782) ([guilhem](https://github.com/guilhem))
## [v1.1.0-rc3](https://github.com/containous/traefik/tree/v1.1.0-rc3) (2016-10-26)
[Full Changelog](https://github.com/containous/traefik/compare/v1.1.0-rc2...v1.1.0-rc3)
**Fixed bugs:**
- Cannot provide multiple certificates using flag [\#757](https://github.com/containous/traefik/issues/757)
- traefik \* Users: unsupported type: slice [\#743](https://github.com/containous/traefik/issues/743)
- \[Docker swarm mode\] The traefik.docker.network seems to have no effect [\#719](https://github.com/containous/traefik/issues/719)
- Case sensitive domain names breaks routing [\#562](https://github.com/containous/traefik/issues/562)
**Closed issues:**
- dependencies installation error [\#755](https://github.com/containous/traefik/issues/755)
- k8s provider w/ acme? [\#752](https://github.com/containous/traefik/issues/752)
- Documented ProvidersThrottleDuration value is invalid [\#741](https://github.com/containous/traefik/issues/741)
- Loadbalaning issues with traefik and Docker Swarm cluster [\#730](https://github.com/containous/traefik/issues/730)
- issues with marathon app ids containing a dot [\#726](https://github.com/containous/traefik/issues/726)
- How Routing traffic depending on path not domain in docker [\#706](https://github.com/containous/traefik/issues/706)
- Traefik crashes when using Consul catalog [\#699](https://github.com/containous/traefik/issues/699)
- File Watcher for rules does not work [\#683](https://github.com/containous/traefik/issues/683)
**Merged pull requests:**
- Fix ResponseRecorder Flush [\#776](https://github.com/containous/traefik/pull/776) ([emilevauge](https://github.com/emilevauge))
- Use sdnotify for systemd [\#768](https://github.com/containous/traefik/pull/768) ([guilhem](https://github.com/guilhem))
- Fix providers throttle duration doc [\#760](https://github.com/containous/traefik/pull/760) ([emilevauge](https://github.com/emilevauge))
- Fix mapstructure issue with anonymous slice [\#759](https://github.com/containous/traefik/pull/759) ([emilevauge](https://github.com/emilevauge))
- Fix multiple certificates using flag [\#758](https://github.com/containous/traefik/pull/758) ([emilevauge](https://github.com/emilevauge))
- Really fix deploy ghr... [\#748](https://github.com/containous/traefik/pull/748) ([emilevauge](https://github.com/emilevauge))
## [v1.1.0-rc2](https://github.com/containous/traefik/tree/v1.1.0-rc2) (2016-10-17)
[Full Changelog](https://github.com/containous/traefik/compare/v1.1.0-rc1...v1.1.0-rc2)

View File

@@ -52,7 +52,7 @@ Run it and forget it!
- Circuit breakers on backends
- Round Robin, rebalancer load-balancers
- Rest Metrics
- [Tiny](https://imagelayers.io/?images=traefik) [official](https://hub.docker.com/r/_/traefik/) docker image included
- [Tiny](https://microbadger.com/images/traefik) [official](https://hub.docker.com/r/_/traefik/) docker image included
- SSL backends support
- SSL frontend support (with SNI)
- Clean AngularJS Web UI
@@ -159,9 +159,10 @@ Founded in 2014, Asteris creates next-generation infrastructure software for the
- Emile Vauge [@emilevauge](https://github.com/emilevauge)
- Vincent Demeester [@vdemeester](https://github.com/vdemeester)
- Samuel Berthe [@samber](https://github.com/samber)
- Russell Clare [@Russell-IO](https://github.com/Russell-IO)
- Ed Robinson [@errm](https://github.com/errm)
- Daniel Tomcej [@dtomcej](https://github.com/dtomcej)
- Manuel Laufenberg [@SantoDE](https://github.com/SantoDE)
## Credits

View File

@@ -119,11 +119,12 @@ func (a *ACME) CreateClusterConfig(leadership *cluster.Leadership, tlsConfig *tl
}
datastore, err := cluster.NewDataStore(
leadership.Pool.Ctx(),
staert.KvSource{
Store: leadership.Store,
Prefix: a.Storage,
},
leadership.Pool.Ctx(), &Account{},
&Account{},
listener)
if err != nil {
return err
@@ -136,12 +137,14 @@ func (a *ACME) CreateClusterConfig(leadership *cluster.Leadership, tlsConfig *tl
leadership.Pool.AddGoCtx(func(ctx context.Context) {
log.Infof("Starting ACME renew job...")
defer log.Infof("Stopped ACME renew job...")
select {
case <-ctx.Done():
return
case <-ticker.C:
if err := a.renewCertificates(); err != nil {
log.Errorf("Error renewing ACME certificate: %s", err.Error())
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
if err := a.renewCertificates(); err != nil {
log.Errorf("Error renewing ACME certificate: %s", err.Error())
}
}
}
})
@@ -251,7 +254,6 @@ func (a *ACME) CreateLocalConfig(tlsConfig *tls.Config, checkOnDemandDomain func
needRegister = true
}
log.Infof("buildACMEClient...")
a.client, err = a.buildACMEClient(account)
if err != nil {
return err
@@ -269,7 +271,7 @@ func (a *ACME) CreateLocalConfig(tlsConfig *tls.Config, checkOnDemandDomain func
// The client has a URL to the current Let's Encrypt Subscriber
// Agreement. The user will need to agree to it.
log.Infof("AgreeToTOS...")
log.Debugf("AgreeToTOS...")
err = a.client.AgreeToTOS()
if err != nil {
// Let's Encrypt Subscriber Agreement renew ?
@@ -373,11 +375,6 @@ func (a *ACME) renewCertificates() error {
account := a.store.Get().(*Account)
for _, certificateResource := range account.DomainsCertificate.Certs {
if certificateResource.needRenew() {
transaction, object, err := a.store.Begin()
if err != nil {
return err
}
account = object.(*Account)
log.Debugf("Renewing certificate %+v", certificateResource.Domains)
renewedCert, err := a.client.RenewCertificate(acme.CertificateResource{
Domain: certificateResource.Certificate.Domain,
@@ -398,6 +395,11 @@ func (a *ACME) renewCertificates() error {
PrivateKey: renewedCert.PrivateKey,
Certificate: renewedCert.Certificate,
}
transaction, object, err := a.store.Begin()
if err != nil {
return err
}
account = object.(*Account)
err = account.DomainsCertificate.renewCertificates(renewedACMECert, certificateResource.Domains)
if err != nil {
log.Errorf("Error renewing certificate: %v", err)

View File

@@ -68,7 +68,7 @@ func (t *localTransaction) Commit(object cluster.Object) error {
t.LocalStore.account = object.(*Account)
defer t.storageLock.Unlock()
if t.dirty {
return fmt.Errorf("Transaction already used. Please begin a new one.")
return fmt.Errorf("transaction already used, please begin a new one")
}
// write account to file

View File

@@ -56,7 +56,7 @@ type Datastore struct {
}
// NewDataStore creates a Datastore
func NewDataStore(kvSource staert.KvSource, ctx context.Context, object Object, listener Listener) (*Datastore, error) {
func NewDataStore(ctx context.Context, kvSource staert.KvSource, object Object, listener Listener) (*Datastore, error) {
datastore := Datastore{
kv: kvSource,
ctx: ctx,
@@ -230,7 +230,7 @@ func (s *datastoreTransaction) Commit(object Object) error {
s.localLock.Lock()
defer s.localLock.Unlock()
if s.dirty {
return fmt.Errorf("Transaction already used. Please begin a new one.")
return fmt.Errorf("transaction already used, please begin a new one")
}
s.Datastore.meta.object = object
err := s.Datastore.meta.Marshall()

View File

@@ -39,7 +39,7 @@ func (l *Leadership) Participate(pool *safe.Pool) {
defer log.Debugf("Node %s no more running for election", l.Cluster.Node)
backOff := backoff.NewExponentialBackOff()
operation := func() error {
return l.run(l.candidate, ctx)
return l.run(ctx, l.candidate)
}
notify := func(err error, time time.Duration) {
@@ -63,7 +63,7 @@ func (l *Leadership) Resign() {
log.Infof("Node %s resigned", l.Cluster.Node)
}
func (l *Leadership) run(candidate *leadership.Candidate, ctx context.Context) error {
func (l *Leadership) run(ctx context.Context, candidate *leadership.Candidate) error {
electedCh, errCh := candidate.RunForElection()
for {
select {

View File

@@ -25,10 +25,11 @@ type TraefikConfiguration struct {
type GlobalConfiguration struct {
GraceTimeOut int64 `short:"g" description:"Duration to give active requests a chance to finish during hot-reload"`
Debug bool `short:"d" description:"Enable debug mode"`
CheckNewVersion bool `description:"Periodically check if a new version has been released"`
AccessLogsFile string `description:"Access logs file"`
TraefikLogsFile string `description:"Traefik logs file"`
LogLevel string `short:"l" description:"Log level"`
EntryPoints EntryPoints `description:"Entrypoints definition using format: --entryPoints='Name:http Address::8000 Redirect.EntryPoint:https' --entryPoints='Name:https Address::4442 TLS:tests/traefik.crt,tests/traefik.key'"`
EntryPoints EntryPoints `description:"Entrypoints definition using format: --entryPoints='Name:http Address::8000 Redirect.EntryPoint:https' --entryPoints='Name:https Address::4442 TLS:tests/traefik.crt,tests/traefik.key;prod/traefik.crt,prod/traefik.key'"`
Cluster *types.Cluster `description:"Enable clustering"`
Constraints types.Constraints `description:"Filter services by constraint, matching with service tags"`
ACME *acme.ACME `description:"Enable ACME (Let's Encrypt): automatic SSL"`
@@ -233,10 +234,10 @@ func (certs *Certificates) CreateTLSConfig() (*tls.Config, error) {
if errKey == nil {
isAPath = true
} else {
return nil, fmt.Errorf("Bad TLS Certificate KeyFile format. Expected a path.")
return nil, fmt.Errorf("bad TLS Certificate KeyFile format, expected a path")
}
} else if errKey == nil {
return nil, fmt.Errorf("Bad TLS Certificate KeyFile format. Expected a path.")
return nil, fmt.Errorf("bad TLS Certificate KeyFile format, expected a path")
}
cert := tls.Certificate{}
@@ -263,21 +264,28 @@ func (certs *Certificates) String() string {
if len(*certs) == 0 {
return ""
}
return (*certs)[0].CertFile + "," + (*certs)[0].KeyFile
var result []string
for _, certificate := range *certs {
result = append(result, certificate.CertFile+","+certificate.KeyFile)
}
return strings.Join(result, ";")
}
// Set is the method to set the flag value, part of the flag.Value interface.
// Set's argument is a string to be parsed to set the flag.
// It's a comma-separated list, so we split it.
func (certs *Certificates) Set(value string) error {
files := strings.Split(value, ",")
if len(files) != 2 {
return errors.New("Bad certificates format: " + value)
certificates := strings.Split(value, ";")
for _, certificate := range certificates {
files := strings.Split(certificate, ",")
if len(files) != 2 {
return errors.New("Bad certificates format: " + value)
}
*certs = append(*certs, Certificate{
CertFile: files[0],
KeyFile: files[1],
})
}
*certs = append(*certs, Certificate{
CertFile: files[0],
KeyFile: files[1],
})
return nil
}
@@ -321,54 +329,54 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
defaultMarathon.Watch = true
defaultMarathon.Endpoint = "http://127.0.0.1:8080"
defaultMarathon.ExposedByDefault = true
defaultMarathon.Constraints = []types.Constraint{}
defaultMarathon.Constraints = types.Constraints{}
// default Consul
var defaultConsul provider.Consul
defaultConsul.Watch = true
defaultConsul.Endpoint = "127.0.0.1:8500"
defaultConsul.Prefix = "traefik"
defaultConsul.Constraints = []types.Constraint{}
defaultConsul.Constraints = types.Constraints{}
// default ConsulCatalog
var defaultConsulCatalog provider.ConsulCatalog
defaultConsulCatalog.Endpoint = "127.0.0.1:8500"
defaultConsulCatalog.Constraints = []types.Constraint{}
defaultConsulCatalog.Constraints = types.Constraints{}
// default Etcd
var defaultEtcd provider.Etcd
defaultEtcd.Watch = true
defaultEtcd.Endpoint = "127.0.0.1:2379"
defaultEtcd.Prefix = "/traefik"
defaultEtcd.Constraints = []types.Constraint{}
defaultEtcd.Constraints = types.Constraints{}
//default Zookeeper
var defaultZookeeper provider.Zookepper
defaultZookeeper.Watch = true
defaultZookeeper.Endpoint = "127.0.0.1:2181"
defaultZookeeper.Prefix = "/traefik"
defaultZookeeper.Constraints = []types.Constraint{}
defaultZookeeper.Constraints = types.Constraints{}
//default Boltdb
var defaultBoltDb provider.BoltDb
defaultBoltDb.Watch = true
defaultBoltDb.Endpoint = "127.0.0.1:4001"
defaultBoltDb.Prefix = "/traefik"
defaultBoltDb.Constraints = []types.Constraint{}
defaultBoltDb.Constraints = types.Constraints{}
//default Kubernetes
var defaultKubernetes provider.Kubernetes
defaultKubernetes.Watch = true
defaultKubernetes.Endpoint = ""
defaultKubernetes.LabelSelector = ""
defaultKubernetes.Constraints = []types.Constraint{}
defaultKubernetes.Constraints = types.Constraints{}
// default Mesos
var defaultMesos provider.Mesos
defaultMesos.Watch = true
defaultMesos.Endpoint = "http://127.0.0.1:5050"
defaultMesos.ExposedByDefault = true
defaultMesos.Constraints = []types.Constraint{}
defaultMesos.Constraints = types.Constraints{}
defaultConfiguration := GlobalConfiguration{
Docker: &defaultDocker,
@@ -398,10 +406,11 @@ func NewTraefikConfiguration() *TraefikConfiguration {
TraefikLogsFile: "",
LogLevel: "ERROR",
EntryPoints: map[string]*EntryPoint{},
Constraints: []types.Constraint{},
Constraints: types.Constraints{},
DefaultEntryPoints: []string{},
ProvidersThrottleDuration: time.Duration(2 * time.Second),
MaxIdleConnsPerHost: 200,
CheckNewVersion: true,
},
ConfigFile: "",
}

View File

@@ -2,6 +2,7 @@
Description=Traefik
[Service]
Type=notify
ExecStart=/usr/bin/traefik --configFile=/etc/traefik.toml
Restart=on-failure

View File

@@ -40,10 +40,15 @@ Run it and forget it!
You can have a quick look at Træfɪk in this [Katacoda tutorial](https://www.katacoda.com/courses/traefik/deploy-load-balancer) that shows how to load balance requests between multiple Docker containers.
Here is a talk (in french) given by [Emile Vauge](https://github.com/emilevauge) at the [Devoxx France 2016](http://www.devoxx.fr) conference.
You will learn fundamental Træfɪk features and see some demos with Docker, Mesos/Marathon and Lets'Encrypt.
Here is a talk given by [Ed Robinson](https://github.com/errm) at the [ContainerCamp UK](https://container.camp) conference.
You will learn fundamental Træfɪk features and see some demos with Kubernetes.
[![Traefik Devoxx France](https://img.youtube.com/vi/QvAz9mVx5TI/0.jpg)](https://www.youtube.com/watch?v=QvAz9mVx5TI)
[![Traefik ContainerCamp UK](http://img.youtube.com/vi/aFtpIShV60I/0.jpg)](https://www.youtube.com/watch?v=aFtpIShV60I)
Here is a talk (in French) given by [Emile Vauge](https://github.com/emilevauge) at the [Devoxx France 2016](http://www.devoxx.fr) conference.
You will learn fundamental Træfɪk features and see some demos with Docker, Mesos/Marathon and Let's Encrypt.
[![Traefik Devoxx France](http://img.youtube.com/vi/QvAz9mVx5TI/0.jpg)](http://www.youtube.com/watch?v=QvAz9mVx5TI)
## Get it

View File

@@ -9,6 +9,28 @@
# Global configuration
################################################################
# Timeout in seconds.
# Duration to give active requests a chance to finish during hot-reloads
#
# Optional
# Default: 10
#
# graceTimeOut = 10
# Enable debug mode
#
# Optional
# Default: false
#
# debug = true
# Periodically check if a new version has been released
#
# Optional
# Default: true
#
# checkNewVersion = false
# Traefik logs file
# If not defined, logs to stdout
#
@@ -31,14 +53,14 @@
#
# logLevel = "ERROR"
# Backends throttle duration: minimum duration between 2 events from providers
# Backends throttle duration: minimum duration in seconds between 2 events from providers
# before applying a new configuration. It avoids unnecessary reloads if multiples events
# are sent in a short amount of time.
#
# Optional
# Default: "2s"
# Default: "2"
#
# ProvidersThrottleDuration = "5s"
# ProvidersThrottleDuration = "5"
# If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used.
# If you encounter 'too many open files' errors, you can either change this value, or change `ulimit` value.

24
glide.lock generated
View File

@@ -1,5 +1,5 @@
hash: 39ff28cc1d13d5915a870b14491ece1849c4eaf5a56cecd50a7676ecee6c6143
updated: 2016-10-06T14:06:39.455848971+02:00
hash: 1bbeb842ee639ccc6e2edf8cc13fc2759cb96e3d839a1aec7b7f6af4fb89c8e1
updated: 2016-11-09T19:24:00.762904389+01:00
imports:
- name: github.com/abbot/go-http-auth
version: cb4372376e1e00e9f6ab9ec142e029302c9e7140
@@ -24,13 +24,17 @@ imports:
- name: github.com/containous/mux
version: a819b77bba13f0c0cbe36e437bc2e948411b3996
- name: github.com/containous/staert
version: 92329254783dc01174f03302d51d7cf2c9ff84cf
version: 1e26a71803e428fd933f5f9c8e50a26878f53147
- name: github.com/coreos/etcd
version: 1c9e0a0e33051fed6c05c141e6fcbfe5c7f2a899
subpackages:
- client
- pkg/pathutil
- pkg/types
- name: github.com/coreos/go-systemd
version: 43e4800a6165b4e02bb2a36673c54b230d6f7b26
subpackages:
- daemon
- name: github.com/davecgh/go-spew
version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9
subpackages:
@@ -164,6 +168,10 @@ imports:
- proto
- name: github.com/golang/glog
version: fca8c8854093a154ff1eb580aae10276ad6b1b5f
- name: github.com/google/go-github
version: 55263f30529cb06f5b478efc333390b791cfe3b1
subpackages:
- github
- name: github.com/google/go-querystring
version: 9235644dd9e52eeae6fa48efd539fdc351a0af53
subpackages:
@@ -176,6 +184,8 @@ imports:
- api
- name: github.com/hashicorp/go-cleanhttp
version: ad28ea4487f05916463e2423a55166280e8254b5
- name: github.com/hashicorp/go-version
version: e96d3840402619007766590ecea8dd7af1292276
- name: github.com/hashicorp/serf
version: b03bf85930b2349eb04b97c8fac437495296e3e7
subpackages:
@@ -221,7 +231,7 @@ imports:
- name: github.com/miekg/dns
version: 5d001d020961ae1c184f9f8152fdc73810481677
- name: github.com/mitchellh/mapstructure
version: ca63d7c062ee3c9f34db231e352b60012b4fd0c1
version: f3009df150dadf309fdee4a54ed65c124afad715
- name: github.com/moul/http2curl
version: b1479103caacaa39319f75e7f57fc545287fca0d
- name: github.com/NYTimes/gziphandler
@@ -267,12 +277,14 @@ imports:
- codec
- name: github.com/unrolled/render
version: 526faf80cd4b305bb8134abea8d20d5ced74faa6
- name: github.com/urfave/negroni
version: e0e50f7dc431c043cb33f91b09c3419d48b7cff5
- name: github.com/vdemeester/docker-events
version: be74d4929ec1ad118df54349fda4b0cba60f849b
- name: github.com/vdemeester/shakers
version: 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3
- name: github.com/vulcand/oxy
version: 4298f24d572dc554eb984f2ffdf6bdd54d4bd613
version: fcc76b52eb8568540a020b7a99e854d9d752b364
repo: https://github.com/containous/oxy.git
vcs: git
subpackages:
@@ -340,7 +352,7 @@ testImports:
- name: github.com/libkermit/docker-check
version: cbe0ef03b3d23070eac4d00ba8828f2cc7f7e5a3
- name: github.com/spf13/pflag
version: 08b1a584251b5b62f458943640fc8ebd4d50aaa5
version: 5644820622454e71517561946e3d94b9f9db6842
- name: github.com/vbatts/tar-split
version: bd4c5d64c3e9297f410025a3b1bd0c58f659e721
subpackages:

View File

@@ -6,11 +6,11 @@ import:
- fun
- package: github.com/Sirupsen/logrus
- package: github.com/cenk/backoff
- package: github.com/codegangsta/negroni
- package: github.com/urfave/negroni
- package: github.com/containous/flaeg
version: a731c034dda967333efce5f8d276aeff11f8ff87
- package: github.com/vulcand/oxy
version: 4298f24d572dc554eb984f2ffdf6bdd54d4bd613
version: fcc76b52eb8568540a020b7a99e854d9d752b364
repo: https://github.com/containous/oxy.git
vcs: git
subpackages:
@@ -21,7 +21,7 @@ import:
- stream
- utils
- package: github.com/containous/staert
version: 92329254783dc01174f03302d51d7cf2c9ff84cf
version: 1e26a71803e428fd933f5f9c8e50a26878f53147
- package: github.com/docker/engine-api
version: 62043eb79d581a32ea849645277023c550732e52
subpackages:
@@ -102,3 +102,11 @@ import:
- package: github.com/docker/leadership
- package: github.com/satori/go.uuid
version: ^1.1.0
- package: github.com/mitchellh/mapstructure
version: f3009df150dadf309fdee4a54ed65c124afad715
- package: github.com/coreos/go-systemd
version: v12
subpackages:
- daemon
- package: github.com/google/go-github
- package: github.com/hashicorp/go-version

View File

@@ -446,9 +446,9 @@ func (s *ConsulSuite) TestDatastore(c *check.C) {
c.Assert(err, checker.IsNil)
ctx := context.Background()
datastore1, err := cluster.NewDataStore(*kvSource, ctx, &TestStruct{}, nil)
datastore1, err := cluster.NewDataStore(ctx, *kvSource, &TestStruct{}, nil)
c.Assert(err, checker.IsNil)
datastore2, err := cluster.NewDataStore(*kvSource, ctx, &TestStruct{}, nil)
datastore2, err := cluster.NewDataStore(ctx, *kvSource, &TestStruct{}, nil)
c.Assert(err, checker.IsNil)
setter1, _, err := datastore1.Begin()

View File

@@ -30,6 +30,7 @@ func (s *HTTPSSuite) TestWithSNIConfigHandshake(c *check.C) {
tlsConfig := &tls.Config{
InsecureSkipVerify: true,
ServerName: "snitest.com",
NextProtos: []string{"h2", "http/1.1"},
}
conn, err := tls.Dial("tcp", "127.0.0.1:4443", tlsConfig)
c.Assert(err, checker.IsNil, check.Commentf("failed to connect to server"))
@@ -41,6 +42,9 @@ func (s *HTTPSSuite) TestWithSNIConfigHandshake(c *check.C) {
cs := conn.ConnectionState()
err = cs.PeerCertificates[0].VerifyHostname("snitest.com")
c.Assert(err, checker.IsNil, check.Commentf("certificate did not match SNI servername"))
proto := conn.ConnectionState().NegotiatedProtocol
c.Assert(proto, checker.Equals, "h2")
}
// TestWithSNIConfigRoute involves a client sending HTTPS requests with

View File

@@ -9,6 +9,13 @@ import (
"net/http"
)
var (
_ http.ResponseWriter = &ResponseRecorder{}
_ http.Hijacker = &ResponseRecorder{}
_ http.Flusher = &ResponseRecorder{}
_ http.CloseNotifier = &ResponseRecorder{}
)
// Retry is a middleware that retries requests
type Retry struct {
attempts int
@@ -52,6 +59,7 @@ type ResponseRecorder struct {
Body *bytes.Buffer // if non-nil, the bytes.Buffer to append written data to
responseWriter http.ResponseWriter
err error
}
// NewRecorder returns an initialized ResponseRecorder.
@@ -75,10 +83,10 @@ func (rw *ResponseRecorder) Header() http.Header {
// Write always succeeds and writes to rw.Body, if not nil.
func (rw *ResponseRecorder) Write(buf []byte) (int, error) {
if rw.Body != nil {
return rw.Body.Write(buf)
if rw.err != nil {
return 0, rw.err
}
return 0, nil
return rw.Body.Write(buf)
}
// WriteHeader sets rw.Code.
@@ -90,3 +98,24 @@ func (rw *ResponseRecorder) WriteHeader(code int) {
func (rw *ResponseRecorder) Hijack() (net.Conn, *bufio.ReadWriter, error) {
return rw.responseWriter.(http.Hijacker).Hijack()
}
// CloseNotify returns a channel that receives at most a
// single value (true) when the client connection has gone
// away.
func (rw *ResponseRecorder) CloseNotify() <-chan bool {
return rw.responseWriter.(http.CloseNotifier).CloseNotify()
}
// Flush sends any buffered data to the client.
func (rw *ResponseRecorder) Flush() {
_, err := rw.responseWriter.Write(rw.Body.Bytes())
if err != nil {
log.Errorf("Error writing response in ResponseRecorder: %s", err)
rw.err = err
}
rw.Body.Reset()
flusher, ok := rw.responseWriter.(http.Flusher)
if ok {
flusher.Flush()
}
}

View File

@@ -17,7 +17,7 @@ type BoltDb struct {
// Provide allows the provider to provide configurations to traefik
// using the given configuration channel.
func (provider *BoltDb) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error {
func (provider *BoltDb) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
store, err := provider.CreateStore()
if err != nil {
return fmt.Errorf("Failed to Connect to KV store: %v", err)

View File

@@ -17,7 +17,7 @@ type Consul struct {
// Provide allows the provider to provide configurations to traefik
// using the given configuration channel.
func (provider *Consul) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error {
func (provider *Consul) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
store, err := provider.CreateStore()
if err != nil {
return fmt.Errorf("Failed to Connect to KV store: %v", err)

View File

@@ -317,7 +317,7 @@ func (provider *ConsulCatalog) watch(configurationChan chan<- types.ConfigMessag
// Provide allows the provider to provide configurations to traefik
// using the given configuration channel.
func (provider *ConsulCatalog) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error {
func (provider *ConsulCatalog) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
config := api.DefaultConfig()
config.Address = provider.Endpoint
client, err := api.NewClient(config)

View File

@@ -114,7 +114,7 @@ func (provider *Docker) createClient() (client.APIClient, error) {
// Provide allows the provider to provide configurations to traefik
// using the given configuration channel.
func (provider *Docker) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error {
func (provider *Docker) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
provider.Constraints = append(provider.Constraints, constraints...)
// TODO register this routine in pool, and watch for stop channel
safe.Go(func() {
@@ -364,10 +364,6 @@ func (provider *Docker) containerFilter(container dockerData) bool {
log.Debugf("Filtering container without port and no traefik.port label %s", container.Name)
return false
}
if len(container.NetworkSettings.Ports) > 1 && err != nil {
log.Debugf("Filtering container with more than 1 port and no traefik.port label %s", container.Name)
return false
}
if !isContainerEnabled(container, provider.ExposedByDefault) {
log.Debugf("Filtering disabled container %s", container.Name)

View File

@@ -390,6 +390,27 @@ func TestDockerGetPort(t *testing.T) {
},
expected: "8080",
},
{
container: docker.ContainerJSON{
ContainerJSONBase: &docker.ContainerJSONBase{
Name: "test-multi-ports",
},
Config: &container.Config{
Labels: map[string]string{
"traefik.port": "8080",
},
},
NetworkSettings: &docker.NetworkSettings{
NetworkSettingsBase: docker.NetworkSettingsBase{
Ports: nat.PortMap{
"8080/tcp": {},
"80/tcp": {},
},
},
},
},
expected: "8080",
},
}
for _, e := range containers {
@@ -735,7 +756,7 @@ func TestDockerTraefikFilter(t *testing.T) {
{
container: docker.ContainerJSON{
ContainerJSONBase: &docker.ContainerJSONBase{
Name: "container",
Name: "container-multi-ports",
},
Config: &container.Config{},
NetworkSettings: &docker.NetworkSettings{
@@ -748,7 +769,7 @@ func TestDockerTraefikFilter(t *testing.T) {
},
},
exposedByDefault: true,
expected: false,
expected: true,
},
{
container: docker.ContainerJSON{

View File

@@ -17,7 +17,7 @@ type Etcd struct {
// Provide allows the provider to provide configurations to traefik
// using the given configuration channel.
func (provider *Etcd) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error {
func (provider *Etcd) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
store, err := provider.CreateStore()
if err != nil {
return fmt.Errorf("Failed to Connect to KV store: %v", err)

View File

@@ -21,7 +21,7 @@ type File struct {
// Provide allows the provider to provide configurations to traefik
// using the given configuration channel.
func (provider *File) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, _ []types.Constraint) error {
func (provider *File) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Error("Error creating file watcher", err)

View File

@@ -1,6 +1,7 @@
package k8s
import (
"context"
"crypto/tls"
"crypto/x509"
"encoding/json"
@@ -141,20 +142,20 @@ func (c *clientImpl) WatchEndpoints(stopCh <-chan bool) (chan interface{}, chan
// WatchAll returns events in the cluster
func (c *clientImpl) WatchAll(labelSelector string, stopCh <-chan bool) (chan interface{}, chan error, error) {
watchCh := make(chan interface{}, 10)
errCh := make(chan error, 10)
watchCh := make(chan interface{}, 100)
errCh := make(chan error, 100)
stopIngresses := make(chan bool)
stopIngresses := make(chan bool, 10)
chanIngresses, chanIngressesErr, err := c.WatchIngresses(labelSelector, stopIngresses)
if err != nil {
return watchCh, errCh, fmt.Errorf("failed to create watch: %v", err)
}
stopServices := make(chan bool)
stopServices := make(chan bool, 10)
chanServices, chanServicesErr, err := c.WatchServices(stopServices)
if err != nil {
return watchCh, errCh, fmt.Errorf("failed to create watch: %v", err)
}
stopEndpoints := make(chan bool)
stopEndpoints := make(chan bool, 10)
chanEndpoints, chanEndpointsErr, err := c.WatchEndpoints(stopEndpoints)
if err != nil {
return watchCh, errCh, fmt.Errorf("failed to create watch: %v", err)
@@ -257,16 +258,17 @@ func (c *clientImpl) watch(url string, labelSelector string, stopCh <-chan bool)
if err != nil {
return watchCh, errCh, fmt.Errorf("failed to make watch request: GET %q : %v", url, err)
}
ctx, cancel := context.WithCancel(context.Background())
req = req.WithContext(ctx)
request.Client.Transport = request.Transport
res, err := request.Client.Do(req)
if err != nil {
cancel()
return watchCh, errCh, fmt.Errorf("failed to do watch request: GET %q: %v", url, err)
}
go func() {
finishCh := make(chan bool)
defer close(finishCh)
defer close(watchCh)
defer close(errCh)
go func() {
@@ -277,20 +279,15 @@ func (c *clientImpl) watch(url string, labelSelector string, stopCh <-chan bool)
if !strings.Contains(err.Error(), "net/http: request canceled") {
errCh <- fmt.Errorf("failed to decode watch event: GET %q : %v", url, err)
}
finishCh <- true
return
}
watchCh <- eventList
}
}()
select {
case <-stopCh:
go func() {
request.Transport.CancelRequest(req)
}()
<-finishCh
return
}
<-stopCh
go func() {
cancel() // cancel watch request
}()
}()
return watchCh, errCh, nil
}

View File

@@ -94,7 +94,7 @@ func (provider *Kubernetes) createClient() (k8s.Client, error) {
// Provide allows the provider to provide configurations to traefik
// using the given configuration channel.
func (provider *Kubernetes) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error {
func (provider *Kubernetes) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
k8sClient, err := provider.createClient()
if err != nil {
return err
@@ -130,6 +130,7 @@ func (provider *Kubernetes) Provide(configurationChan chan<- types.ConfigMessage
log.Debugf("Received event from kubernetes %+v", event)
templateObjects, err := provider.loadIngresses(k8sClient)
if err != nil {
stopWatch <- true
return err
}
if reflect.DeepEqual(provider.lastConfiguration.Get(), templateObjects) {

View File

@@ -83,7 +83,7 @@ func (provider *Kv) watchKv(configurationChan chan<- types.ConfigMessage, prefix
return nil
}
func (provider *Kv) provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error {
func (provider *Kv) provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
provider.Constraints = append(provider.Constraints, constraints...)
operation := func() error {
if _, err := provider.kvclient.Exists("qmslkjdfmqlskdjfmqlksjazçueznbvbwzlkajzebvkwjdcqmlsfj"); err != nil {

View File

@@ -50,7 +50,7 @@ type lightMarathonClient interface {
// Provide allows the provider to provide configurations to traefik
// using the given configuration channel.
func (provider *Marathon) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error {
func (provider *Marathon) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
provider.Constraints = append(provider.Constraints, constraints...)
operation := func() error {
config := marathon.NewDefaultConfig()
@@ -219,10 +219,7 @@ func (provider *Marathon) taskFilter(task marathon.Task, applications *marathon.
log.Debugf("Filtering marathon task %s specifying both traefik.portIndex and traefik.port labels", task.AppID)
return false
}
if portIndexLabel == "" && portValueLabel == "" && len(application.Ports) > 1 {
log.Debugf("Filtering marathon task %s with more than 1 port and no traefik.portIndex or traefik.port label", task.AppID)
return false
}
if portIndexLabel != "" {
index, err := strconv.Atoi((*application.Labels)["traefik.portIndex"])
if err != nil || index < 0 || index > len(application.Ports)-1 {

View File

@@ -371,30 +371,30 @@ func TestMarathonTaskFilter(t *testing.T) {
},
{
task: marathon.Task{
AppID: "foo",
Ports: []int{80},
AppID: "multiple-ports",
Ports: []int{80, 443},
},
applications: &marathon.Applications{
Apps: []marathon.Application{
{
ID: "foo",
ID: "multiple-ports",
Ports: []int{80, 443},
Labels: &map[string]string{},
},
},
},
expected: false,
expected: true,
exposedByDefault: true,
},
{
task: marathon.Task{
AppID: "foo",
AppID: "disable",
Ports: []int{80},
},
applications: &marathon.Applications{
Apps: []marathon.Application{
{
ID: "foo",
ID: "disable",
Ports: []int{80},
Labels: &map[string]string{
"traefik.enable": "false",
@@ -523,7 +523,7 @@ func TestMarathonTaskFilter(t *testing.T) {
},
{
task: marathon.Task{
AppID: "foo",
AppID: "healthcheck-false",
Ports: []int{80},
HealthCheckResults: []*marathon.HealthCheckResult{
{
@@ -534,7 +534,7 @@ func TestMarathonTaskFilter(t *testing.T) {
applications: &marathon.Applications{
Apps: []marathon.Application{
{
ID: "foo",
ID: "healthcheck-false",
Ports: []int{80},
Labels: &map[string]string{},
HealthChecks: &[]marathon.HealthCheck{
@@ -576,13 +576,13 @@ func TestMarathonTaskFilter(t *testing.T) {
},
{
task: marathon.Task{
AppID: "foo",
AppID: "single-port",
Ports: []int{80},
},
applications: &marathon.Applications{
Apps: []marathon.Application{
{
ID: "foo",
ID: "single-port",
Ports: []int{80},
Labels: &map[string]string{},
},
@@ -593,7 +593,7 @@ func TestMarathonTaskFilter(t *testing.T) {
},
{
task: marathon.Task{
AppID: "foo",
AppID: "healthcheck-alive",
Ports: []int{80},
HealthCheckResults: []*marathon.HealthCheckResult{
{
@@ -604,7 +604,7 @@ func TestMarathonTaskFilter(t *testing.T) {
applications: &marathon.Applications{
Apps: []marathon.Application{
{
ID: "foo",
ID: "healthcheck-alive",
Ports: []int{80},
Labels: &map[string]string{},
HealthChecks: &[]marathon.HealthCheck{
@@ -677,7 +677,7 @@ func TestMarathonTaskFilter(t *testing.T) {
for _, c := range cases {
actual := provider.taskFilter(c.task, c.applications, c.exposedByDefault)
if actual != c.expected {
t.Fatalf("expected %v, got %v", c.expected, actual)
t.Fatalf("App %s: expected %v, got %v", c.task.AppID, c.expected, actual)
}
}
}
@@ -740,7 +740,7 @@ func TestMarathonAppConstraints(t *testing.T) {
MarathonLBCompatibility: c.marathonLBCompatibility,
}
constraint, _ := types.NewConstraint("tag==valid")
provider.Constraints = []types.Constraint{*constraint}
provider.Constraints = types.Constraints{constraint}
actual := provider.applicationFilter(c.application, c.filteredTasks)
if actual != c.expected {
t.Fatalf("expected %v, got %v: %v", c.expected, actual, c.application)
@@ -820,7 +820,7 @@ func TestMarathonTaskConstraints(t *testing.T) {
MarathonLBCompatibility: c.marathonLBCompatibility,
}
constraint, _ := types.NewConstraint("tag==valid")
provider.Constraints = []types.Constraint{*constraint}
provider.Constraints = types.Constraints{constraint}
apps := new(marathon.Applications)
apps.Apps = c.applications
actual := provider.taskFilter(c.filteredTask, apps, true)
@@ -927,12 +927,12 @@ func TestMarathonGetPort(t *testing.T) {
{
applications: []marathon.Application{
{
ID: "test1",
ID: "multiple-ports-take-first",
Labels: &map[string]string{},
},
},
task: marathon.Task{
AppID: "test1",
AppID: "multiple-ports-take-first",
Ports: []int{80, 443},
},
expected: "80",

View File

@@ -42,7 +42,7 @@ type Mesos struct {
// Provide allows the provider to provide configurations to traefik
// using the given configuration channel.
func (provider *Mesos) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error {
func (provider *Mesos) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
operation := func() error {
// initialize logging
@@ -212,10 +212,6 @@ func mesosTaskFilter(task state.Task, exposedByDefaultFlag bool) bool {
log.Debugf("Filtering mesos task %s specifying both traefik.portIndex and traefik.port labels", task.Name)
return false
}
if portIndexLabel == "" && portValueLabel == "" && len(task.DiscoveryInfo.Ports.DiscoveryPorts) > 1 {
log.Debugf("Filtering mesos task %s with more than 1 port and no traefik.portIndex or traefik.port label", task.Name)
return false
}
if portIndexLabel != "" {
index, err := strconv.Atoi(labels(task, "traefik.portIndex"))
if err != nil || index < 0 || index > len(task.DiscoveryInfo.Ports.DiscoveryPorts)-1 {

View File

@@ -95,7 +95,7 @@ func TestMesosTaskFilter(t *testing.T) {
setLabels("traefik.enable", "true"),
discovery(setDiscoveryPorts("TCP", 80, "WEB HTTP", "TCP", 443, "WEB HTTPS")),
),
expected: false, // more than 1 discovery port but no traefik.port* label
expected: true, // Default to first index
exposedByDefault: true,
},
{

View File

@@ -23,7 +23,7 @@ import (
type Provider interface {
// Provide allows the provider to provide configurations to traefik
// using the given configuration channel.
Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error
Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error
}
// BaseProvider should be inherited by providers
@@ -44,7 +44,7 @@ func (p *BaseProvider) MatchConstraints(tags []string) (bool, *types.Constraint)
for _, constraint := range p.Constraints {
// xor: if ok and constraint.MustMatch are equal, then no tag is currently matching with the constraint
if ok := constraint.MatchConstraintWithAtLeastOneTag(tags); ok != constraint.MustMatch {
return false, &constraint
return false, constraint
}
}

View File

@@ -230,13 +230,13 @@ func TestNilClientTLS(t *testing.T) {
func TestMatchingConstraints(t *testing.T) {
cases := []struct {
constraints []types.Constraint
constraints types.Constraints
tags []string
expected bool
}{
// simple test: must match
{
constraints: []types.Constraint{
constraints: types.Constraints{
{
Key: "tag",
MustMatch: true,
@@ -250,7 +250,7 @@ func TestMatchingConstraints(t *testing.T) {
},
// simple test: must match but does not match
{
constraints: []types.Constraint{
constraints: types.Constraints{
{
Key: "tag",
MustMatch: true,
@@ -264,7 +264,7 @@ func TestMatchingConstraints(t *testing.T) {
},
// simple test: must not match
{
constraints: []types.Constraint{
constraints: types.Constraints{
{
Key: "tag",
MustMatch: false,
@@ -278,7 +278,7 @@ func TestMatchingConstraints(t *testing.T) {
},
// complex test: globbing
{
constraints: []types.Constraint{
constraints: types.Constraints{
{
Key: "tag",
MustMatch: true,
@@ -292,7 +292,7 @@ func TestMatchingConstraints(t *testing.T) {
},
// complex test: multiple constraints
{
constraints: []types.Constraint{
constraints: types.Constraints{
{
Key: "tag",
MustMatch: true,

View File

@@ -17,7 +17,7 @@ type Zookepper struct {
// Provide allows the provider to provide configurations to traefik
// using the given configuration channel.
func (provider *Zookepper) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error {
func (provider *Zookepper) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
store, err := provider.CreateStore()
if err != nil {
return fmt.Errorf("Failed to Connect to KV store: %v", err)

View File

@@ -45,7 +45,7 @@ func (r *Rules) hostRegexp(hosts ...string) *mux.Route {
func (r *Rules) path(paths ...string) *mux.Route {
router := r.route.route.Subrouter()
for _, path := range paths {
router.Path(types.CanonicalDomain(path))
router.Path(strings.TrimSpace(path))
}
return r.route.route
}
@@ -53,7 +53,7 @@ func (r *Rules) path(paths ...string) *mux.Route {
func (r *Rules) pathPrefix(paths ...string) *mux.Route {
router := r.route.route.Subrouter()
for _, path := range paths {
router.PathPrefix(types.CanonicalDomain(path))
router.PathPrefix(strings.TrimSpace(path))
}
return r.route.route
}
@@ -69,7 +69,7 @@ func (r *Rules) pathStrip(paths ...string) *mux.Route {
r.route.stripPrefixes = paths
router := r.route.route.Subrouter()
for _, path := range paths {
router.Path(types.CanonicalDomain(path))
router.Path(strings.TrimSpace(path))
}
return r.route.route
}
@@ -79,7 +79,7 @@ func (r *Rules) pathPrefixStrip(paths ...string) *mux.Route {
r.route.stripPrefixes = paths
router := r.route.route.Subrouter()
for _, path := range paths {
router.PathPrefix(types.CanonicalDomain(path))
router.PathPrefix(strings.TrimSpace(path))
}
return r.route.route
}

View File

@@ -40,15 +40,23 @@ func TestParseTwoRules(t *testing.T) {
routeResult, err := rules.Parse(expression)
if err != nil {
t.Fatal("Error while building route for Host:foo.bar;Path:/foobar")
t.Fatal("Error while building route for Host:foo.bar;Path:/FOObar")
}
request, err := http.NewRequest("GET", "http://foo.bar/foobar", nil)
routeMatch := routeResult.Match(request, &mux.RouteMatch{Route: routeResult})
if routeMatch == true {
t.Log(err)
t.Fatal("Rule Host:foo.bar;Path:/FOObar don't match")
}
request, err = http.NewRequest("GET", "http://foo.bar/FOObar", nil)
routeMatch = routeResult.Match(request, &mux.RouteMatch{Route: routeResult})
if routeMatch == false {
t.Log(err)
t.Fatal("Rule Host:foo.bar;Path:/foobar don't match")
t.Fatal("Rule Host:foo.bar;Path:/FOObar don't match")
}
}

View File

@@ -27,7 +27,7 @@ OS_ARCH_ARG=(386 amd64)
for OS in ${OS_PLATFORM_ARG[@]}; do
for ARCH in ${OS_ARCH_ARG[@]}; do
echo "Building binary for $OS/$ARCH..."
GOARCH=$ARCH GOOS=$OS CGO_ENABLED=0 go build -ldflags "-s -w -X main.Version=$VERSION -X main.Codename=$CODENAME -X main.BuildDate=$DATE" -o "dist/traefik_$OS-$ARCH" .
GOARCH=$ARCH GOOS=$OS CGO_ENABLED=0 go build -ldflags "-s -w -X github.com/containous/traefik/version.Version=$VERSION -X github.com/containous/traefik/version.Codename=$CODENAME -X github.com/containous/traefik/version.BuildDate=$DATE" -o "dist/traefik_$OS-$ARCH" .
done
done
@@ -38,6 +38,6 @@ OS_ARCH_ARG=(arm arm64)
for OS in ${OS_PLATFORM_ARG[@]}; do
for ARCH in ${OS_ARCH_ARG[@]}; do
echo "Building binary for $OS/$ARCH..."
GOARCH=$ARCH GOOS=$OS CGO_ENABLED=0 go build -ldflags "-s -w -X main.Version=$VERSION -X main.Codename=$CODENAME -X main.BuildDate=$DATE" -o "dist/traefik_$OS-$ARCH" .
GOARCH=$ARCH GOOS=$OS CGO_ENABLED=0 go build -ldflags "-s -w -X github.com/containous/traefik/version.Version=$VERSION -X github.com/containous/traefik/version.Codename=$CODENAME -X github.com/containous/traefik/version.BuildDate=$DATE" -o "dist/traefik_$OS-$ARCH" .
done
done
done

View File

@@ -91,7 +91,7 @@ func NewServer(globalConfiguration GlobalConfiguration) *Server {
return server
}
// Start starts the server and blocks until server is shutted down.
// Start starts the server.
func (server *Server) Start() {
server.startHTTPServers()
server.startLeadership()
@@ -104,6 +104,10 @@ func (server *Server) Start() {
server.configureProviders()
server.startProviders()
go server.listenSignals()
}
// Wait blocks until server is shutted down.
func (server *Server) Wait() {
<-server.stopChan
}
@@ -208,11 +212,11 @@ func (server *Server) listenProviders(stop chan bool) {
lastConfigs.Set(configMsg.ProviderName, &configMsg)
lastReceivedConfigurationValue := lastReceivedConfiguration.Get().(time.Time)
if time.Now().After(lastReceivedConfigurationValue.Add(time.Duration(server.globalConfiguration.ProvidersThrottleDuration))) {
log.Debugf("Last %s config received more than %s, OK", configMsg.ProviderName, server.globalConfiguration.ProvidersThrottleDuration)
log.Debugf("Last %s config received more than %s, OK", configMsg.ProviderName, server.globalConfiguration.ProvidersThrottleDuration.String())
// last config received more than n s ago
server.configurationValidatedChan <- configMsg
} else {
log.Debugf("Last %s config received less than %s, waiting...", configMsg.ProviderName, server.globalConfiguration.ProvidersThrottleDuration)
log.Debugf("Last %s config received less than %s, waiting...", configMsg.ProviderName, server.globalConfiguration.ProvidersThrottleDuration.String())
safe.Go(func() {
<-time.After(server.globalConfiguration.ProvidersThrottleDuration)
lastReceivedConfigurationValue := lastReceivedConfiguration.Get().(time.Time)
@@ -379,6 +383,9 @@ func (server *Server) createTLSConfig(entryPointName string, tlsOption *TLS, rou
return nil, err
}
// ensure http2 enabled
config.NextProtos = []string{"h2", "http/1.1"}
if len(tlsOption.ClientCAFiles) > 0 {
pool := x509.NewCertPool()
for _, caFile := range tlsOption.ClientCAFiles {

View File

@@ -11,6 +11,7 @@ import (
"runtime"
"strings"
"text/template"
"time"
"github.com/Sirupsen/logrus"
"github.com/containous/flaeg"
@@ -20,8 +21,10 @@ import (
"github.com/containous/traefik/log"
"github.com/containous/traefik/middlewares"
"github.com/containous/traefik/provider"
"github.com/containous/traefik/safe"
"github.com/containous/traefik/types"
"github.com/containous/traefik/version"
"github.com/coreos/go-systemd/daemon"
"github.com/docker/libkv/store"
"github.com/satori/go.uuid"
)
@@ -261,6 +264,20 @@ func run(traefikConfiguration *TraefikConfiguration) {
}
jsonConf, _ := json.Marshal(globalConfiguration)
log.Infof("Traefik version %s built on %s", version.Version, version.BuildDate)
if globalConfiguration.CheckNewVersion {
ticker := time.NewTicker(24 * time.Hour)
safe.Go(func() {
version.CheckNewVersion()
for {
select {
case <-ticker.C:
version.CheckNewVersion()
}
}
})
}
if len(traefikConfiguration.ConfigFile) != 0 {
log.Infof("Using TOML configuration file %s", traefikConfiguration.ConfigFile)
}
@@ -268,6 +285,11 @@ func run(traefikConfiguration *TraefikConfiguration) {
server := NewServer(globalConfiguration)
server.Start()
defer server.Close()
sent, err := daemon.SdNotify("READY=1")
if !sent && err != nil {
log.Error("Fail to notify", err)
}
server.Wait()
log.Info("Shutting down")
}

View File

@@ -10,6 +10,20 @@
#
# graceTimeOut = 10
# Enable debug mode
#
# Optional
# Default: false
#
# debug = true
# Periodically check if a new version has been released
#
# Optional
# Default: true
#
# checkNewVersion = false
# Traefik logs file
# If not defined, logs to stdout
#
@@ -30,14 +44,14 @@
#
# logLevel = "ERROR"
# Backends throttle duration: minimum duration between 2 events from providers
# Backends throttle duration: minimum duration in seconds between 2 events from providers
# before applying a new configuration. It avoids unnecessary reloads if multiples events
# are sent in a short amount of time.
#
# Optional
# Default: "2s"
# Default: "2"
#
# ProvidersThrottleDuration = "5s"
# ProvidersThrottleDuration = "5"
# If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used.
# If you encounter 'too many open files' errors, you can either change this value, or change `ulimit` value.

View File

@@ -1,6 +1,7 @@
package types
import (
"encoding"
"errors"
"fmt"
"github.com/docker/libkv/store"
@@ -141,11 +142,25 @@ func (c *Constraint) String() string {
return c.Key + "!=" + c.Regex
}
var _ encoding.TextUnmarshaler = (*Constraint)(nil)
// UnmarshalText define how unmarshal in TOML parsing
func (c *Constraint) UnmarshalText(text []byte) error {
constraint, err := NewConstraint(string(text))
*c = *constraint
return err
if err != nil {
return err
}
c.Key = constraint.Key
c.MustMatch = constraint.MustMatch
c.Regex = constraint.Regex
return nil
}
var _ encoding.TextMarshaler = (*Constraint)(nil)
// MarshalText encodes the receiver into UTF-8-encoded text and returns the result.
func (c *Constraint) MarshalText() (text []byte, err error) {
return []byte(c.String()), nil
}
// MatchConstraintWithAtLeastOneTag tests a constraint for one single service
@@ -169,16 +184,16 @@ func (cs *Constraints) Set(str string) error {
if err != nil {
return err
}
*cs = append(*cs, *constraint)
*cs = append(*cs, constraint)
}
return nil
}
// Constraints holds a Constraint parser
type Constraints []Constraint
type Constraints []*Constraint
//Get []*Constraint
func (cs *Constraints) Get() interface{} { return []Constraint(*cs) }
func (cs *Constraints) Get() interface{} { return []*Constraint(*cs) }
//String returns []*Constraint in string
func (cs *Constraints) String() string { return fmt.Sprintf("%+v", *cs) }
@@ -216,12 +231,12 @@ type Users []string
// Basic HTTP basic authentication
type Basic struct {
Users
Users `mapstructure:","`
}
// Digest HTTP authentication
type Digest struct {
Users
Users `mapstructure:","`
}
// CanonicalDomain returns a lower case domain with trim space

View File

@@ -1,5 +1,12 @@
package version
import (
"github.com/containous/traefik/log"
"github.com/google/go-github/github"
goversion "github.com/hashicorp/go-version"
"net/url"
)
var (
// Version holds the current version of traefik.
Version = "dev"
@@ -8,3 +15,50 @@ var (
// BuildDate holds the build date of traefik.
BuildDate = "I don't remember exactly"
)
// CheckNewVersion checks if a new version is available
func CheckNewVersion() {
if Version == "dev" {
return
}
client := github.NewClient(nil)
updateURL, err := url.Parse("https://update.traefik.io")
if err != nil {
log.Warnf("Error checking new version: %s", err)
return
}
client.BaseURL = updateURL
releases, resp, err := client.Repositories.ListReleases("containous", "traefik", nil)
if err != nil {
log.Warnf("Error checking new version: %s", err)
return
}
if resp.StatusCode != 200 {
log.Warnf("Error checking new version: status=%s", resp.Status)
return
}
currentVersion, err := goversion.NewVersion(Version)
if err != nil {
log.Warnf("Error checking new version: %s", err)
return
}
for _, release := range releases {
releaseVersion, err := goversion.NewVersion(*release.TagName)
if err != nil {
log.Warnf("Error checking new version: %s", err)
return
}
if len(currentVersion.Prerelease()) == 0 && len(releaseVersion.Prerelease()) > 0 {
continue
}
if releaseVersion.GreaterThan(currentVersion) {
log.Warnf("A new release has been found: %s. Please consider updating.", releaseVersion.String())
return
}
}
}

2
web.go
View File

@@ -50,7 +50,7 @@ func goroutines() interface{} {
// Provide allows the provider to provide configurations to traefik
// using the given configuration channel.
func (provider *WebProvider) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, _ []types.Constraint) error {
func (provider *WebProvider) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, _ types.Constraints) error {
systemRouter := mux.NewRouter()

View File

@@ -21,7 +21,8 @@
"angular-ui-bootstrap": "^2.0.0",
"angular-ui-router": "^0.3.1",
"bootstrap": "^3.3.6",
"moment": "^2.14.1"
"moment": "^2.14.1",
"nvd3": "^1.8.4"
},
"devDependencies": {
"angular-mocks": "^1.4.2",
@@ -80,11 +81,6 @@
"test": "gulp test",
"test:auto": "gulp test:auto"
},
"overrides": {
"angular-nvd3": {
"main": "dist/angular-nvd3.js"
}
},
"eslintConfig": {
"globals": {
"expect": true