Compare commits

...

12 Commits
v1.4.4 ... v1.4

Author SHA1 Message Date
Fernandez Ludovic
145a485255 fix: mkdocs.yml 2023-01-23 11:04:07 +01:00
mmatur
d3839eae6a feat: add dockerfile for documentation 2021-10-05 10:23:25 +02:00
Fernandez Ludovic
3c96dd3014 doc: fix version in requirements.txt 2018-09-28 23:16:28 +02:00
Michael
741c739ef1 Prepare release v1.4.6 2018-01-02 12:54:03 +01:00
SALLEYRON Julien
52f16e11a8 Use gorilla readMessage and writeMessage instead of just an io.Copy 2018-01-02 12:30:05 +01:00
Michael
e8e8b41eed Normalize serviceName added to the service backend names 2018-01-02 10:52:03 +01:00
Ludovic Fernandez
718fc7a79d Fix bug report command 2018-01-02 10:14:03 +01:00
Michael
cda09c843a Prepare release v1.4.5 2017-12-06 10:44:03 +01:00
Mikhail Vasin
ab1a930705 Emphasize the necessity of enabling file backend 2017-12-05 02:30:02 +01:00
Michael
47a5cfbd3e Fix empty ip when container is stopped 2017-11-28 13:58:04 +01:00
Ludovic Fernandez
b572879691 Add link to futur 1.5 documentation. 2017-11-28 13:06:03 +01:00
Kwok-kuen Cheung
0f09551a76 Fix kubernetes path prefix rule with rewrite-target 2017-11-27 11:22:03 +01:00
18 changed files with 179 additions and 42 deletions

View File

@@ -1,5 +1,24 @@
# Change Log
## [v1.4.6](https://github.com/containous/traefik/tree/v1.4.6) (2018-01-02)
[All Commits](https://github.com/containous/traefik/compare/v1.4.5...v1.4.6)
**Bug fixes:**
- **[docker]** Normalize serviceName added to the service backend names ([#2631](https://github.com/containous/traefik/pull/2631) by [mmatur](https://github.com/mmatur))
- **[websocket]** Use gorilla readMessage and writeMessage instead of just an io.Copy ([#2640](https://github.com/containous/traefik/pull/2640) by [Juliens](https://github.com/Juliens))
- Fix bug report command ([#2638](https://github.com/containous/traefik/pull/2638) by [ldez](https://github.com/ldez))
## [v1.4.5](https://github.com/containous/traefik/tree/v1.4.5) (2017-12-05)
[All Commits](https://github.com/containous/traefik/compare/v1.4.4...v1.4.5)
**Bug fixes:**
- **[docker]** Fix empty ip when container is stopped ([#2478](https://github.com/containous/traefik/pull/2478) by [mmatur](https://github.com/mmatur))
- **[k8s]** Fix kubernetes path prefix rule with rewrite-target ([#2461](https://github.com/containous/traefik/pull/2461) by [cheungpat](https://github.com/cheungpat))
**Documentation:**
- **[file]** Emphasize the necessity of enabling file backend ([#2483](https://github.com/containous/traefik/pull/2483) by [mvasin](https://github.com/mvasin))
- Add link to future 1.5 documentation. ([#2477](https://github.com/containous/traefik/pull/2477) by [ldez](https://github.com/ldez))
## [v1.4.4](https://github.com/containous/traefik/tree/v1.4.4) (2017-11-21)
[All Commits](https://github.com/containous/traefik/compare/v1.4.3...v1.4.4)

View File

@@ -84,7 +84,7 @@ Add more configuration information here.
)
// newBugCmd builds a new Bug command
func newBugCmd(traefikConfiguration interface{}, traefikPointersConfiguration interface{}) *flaeg.Command {
func newBugCmd(traefikConfiguration *TraefikConfiguration, traefikPointersConfiguration *TraefikConfiguration) *flaeg.Command {
//version Command init
return &flaeg.Command{
@@ -99,7 +99,7 @@ func newBugCmd(traefikConfiguration interface{}, traefikPointersConfiguration in
}
}
func runBugCmd(traefikConfiguration interface{}) func() error {
func runBugCmd(traefikConfiguration *TraefikConfiguration) func() error {
return func() error {
body, err := createBugReport(traefikConfiguration)
@@ -113,7 +113,7 @@ func runBugCmd(traefikConfiguration interface{}) func() error {
}
}
func createBugReport(traefikConfiguration interface{}) (string, error) {
func createBugReport(traefikConfiguration *TraefikConfiguration) (string, error) {
var version bytes.Buffer
if err := getVersionPrint(&version); err != nil {
return "", err
@@ -124,7 +124,7 @@ func createBugReport(traefikConfiguration interface{}) (string, error) {
return "", err
}
config, err := anonymize.Do(&traefikConfiguration, true)
config, err := anonymize.Do(traefikConfiguration, true)
if err != nil {
return "", err
}

View File

@@ -6,16 +6,27 @@ import (
"github.com/containous/traefik/cmd/traefik/anonymize"
"github.com/containous/traefik/configuration"
"github.com/containous/traefik/provider/file"
"github.com/containous/traefik/types"
"github.com/stretchr/testify/assert"
)
func Test_createBugReport(t *testing.T) {
traefikConfiguration := TraefikConfiguration{
traefikConfiguration := &TraefikConfiguration{
ConfigFile: "FOO",
GlobalConfiguration: configuration.GlobalConfiguration{
EntryPoints: configuration.EntryPoints{
"goo": &configuration.EntryPoint{
Address: "hoo.bar",
Auth: &types.Auth{
Basic: &types.Basic{
UsersFile: "foo Basic UsersFile",
Users: types.Users{"foo Basic Users 1", "foo Basic Users 2", "foo Basic Users 3"},
},
Digest: &types.Digest{
UsersFile: "foo Digest UsersFile",
Users: types.Users{"foo Digest Users 1", "foo Digest Users 2", "foo Digest Users 3"},
},
},
},
},
File: &file.Provider{
@@ -27,6 +38,11 @@ func Test_createBugReport(t *testing.T) {
report, err := createBugReport(traefikConfiguration)
assert.NoError(t, err, report)
// exported anonymous configuration
assert.NotContains(t, "web Basic Users ", report)
assert.NotContains(t, "foo Digest Users ", report)
assert.NotContains(t, "hoo.bar", report)
}
func Test_anonymize_traefikConfiguration(t *testing.T) {

10
docs.Dockerfile Normal file
View File

@@ -0,0 +1,10 @@
FROM alpine:3.7
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/.local/bin
COPY requirements.txt /mkdocs/
WORKDIR /mkdocs
VOLUME /mkdocs
RUN apk --no-cache --no-progress add py-pip \
&& pip install --user -r requirements.txt

View File

@@ -1,9 +1,15 @@
## Previous documentation
## Current versions documentation
- [Latest stable](https://docs.traefik.io)
- [Experimental](https://master--traefik-docs.netlify.com/)
## Future version documentation
- [v1.5 RC](http://v1-5.archive.docs.traefik.io/)
## Previous versions documentation
- [v1.4 aka Roquefort](http://v1-4.archive.docs.traefik.io/)
- [v1.3 aka Raclette](http://v1-3.archive.docs.traefik.io/)
@@ -14,4 +20,4 @@
## More
[Change log](https://github.com/containous/traefik/blob/master/CHANGELOG.md)
[Change log](https://github.com/containous/traefik/blob/master/CHANGELOG.md)

View File

@@ -8,6 +8,8 @@ You have three choices:
- [Rules in a Separate File](/configuration/backends/file/#rules-in-a-separate-file)
- [Multiple `.toml` Files](/configuration/backends/file/#multiple-toml-files)
To enable the file backend, you must either pass the `--file` option to the Træfik binary or put the `[file]` section (with or without inner settings) in the configuration file.
## Simple
Add your configuration at the end of the global configuration file `traefik.toml`:

2
glide.lock generated
View File

@@ -481,7 +481,7 @@ imports:
- name: github.com/urfave/negroni
version: 490e6a555d47ca891a89a150d0c1ef3922dfffe9
- name: github.com/vulcand/oxy
version: 7e9763c4dc71b9758379da3581e6495c145caaab
version: bf0e6bab094f7b909a8d94ba9d7b74aaf7cc3025
repo: https://github.com/containous/oxy.git
vcs: git
subpackages:

View File

@@ -49,6 +49,14 @@ func (s *DockerSuite) startContainerWithLabels(c *check.C, image string, labels
})
}
func (s *DockerSuite) startContainerWithNameAndLabels(c *check.C, name string, image string, labels map[string]string, args ...string) string {
return s.startContainerWithConfig(c, image, d.ContainerConfig{
Name: name,
Cmd: args,
Labels: labels,
})
}
func (s *DockerSuite) startContainerWithConfig(c *check.C, image string, config d.ContainerConfig) string {
if config.Name == "" {
config.Name = namesgenerator.GetRandomName(10)
@@ -60,6 +68,11 @@ func (s *DockerSuite) startContainerWithConfig(c *check.C, image string, config
return strings.SplitAfter(container.Name, "/")[1]
}
func (s *DockerSuite) stopAndRemoveContainerByName(c *check.C, name string) {
s.project.Stop(c, name)
s.project.Remove(c, name)
}
func (s *DockerSuite) SetUpSuite(c *check.C) {
project := docker.NewProjectFromEnv(c)
s.project = project
@@ -229,3 +242,53 @@ func (s *DockerSuite) TestDockerContainersWithServiceLabels(c *check.C) {
c.Assert(json.Unmarshal(body, &version), checker.IsNil)
c.Assert(version["Version"], checker.Equals, "swarm/1.0.0")
}
func (s *DockerSuite) TestRestartDockerContainers(c *check.C) {
file := s.adaptFileForHost(c, "fixtures/docker/simple.toml")
defer os.Remove(file)
// Start a container with some labels
labels := map[string]string{
types.LabelPrefix + "frontend.rule": "Host:my.super.host",
types.LabelPort: "2375",
}
s.startContainerWithNameAndLabels(c, "powpow", "swarm:1.0.0", labels, "manage", "token://blabla")
// Start traefik
cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/version", nil)
c.Assert(err, checker.IsNil)
req.Host = "my.super.host"
// FIXME Need to wait than 500 milliseconds more (for swarm or traefik to boot up ?)
resp, err := try.ResponseUntilStatusCode(req, 1500*time.Millisecond, http.StatusOK)
c.Assert(err, checker.IsNil)
body, err := ioutil.ReadAll(resp.Body)
c.Assert(err, checker.IsNil)
var version map[string]interface{}
c.Assert(json.Unmarshal(body, &version), checker.IsNil)
c.Assert(version["Version"], checker.Equals, "swarm/1.0.0")
err = try.GetRequest("http://127.0.0.1:8080/api/providers/docker/backends", 60*time.Second, try.BodyContains("powpow"))
c.Assert(err, checker.IsNil)
s.stopAndRemoveContainerByName(c, "powpow")
defer s.project.Remove(c, "powpow")
time.Sleep(5 * time.Second)
err = try.GetRequest("http://127.0.0.1:8080/api/providers/docker/backends", 10*time.Second, try.BodyContains("powpow"))
c.Assert(err, checker.NotNil)
s.startContainerWithNameAndLabels(c, "powpow", "swarm:1.0.0", labels, "manage", "token://blabla")
err = try.GetRequest("http://127.0.0.1:8080/api/providers/docker/backends", 60*time.Second, try.BodyContains("powpow"))
c.Assert(err, checker.IsNil)
}

View File

@@ -6,6 +6,8 @@ logLevel = "DEBUG"
[entryPoints.http]
address = ":8000"
[web]
[docker]
# It's dynamagic !

View File

@@ -25,9 +25,6 @@ google_analytics:
# Options
extra:
logo: img/traefik.logo.png
palette:
primary: 'blue'
accent: 'light blue'
feature:
tabs: false
palette:

View File

@@ -12,14 +12,6 @@ import (
)
func TestConsulCatalogGetFrontendRule(t *testing.T) {
provider := &CatalogProvider{
Domain: "localhost",
Prefix: "traefik",
FrontEndRule: "Host:{{.ServiceName}}.{{.Domain}}",
frontEndRuleTemplate: template.New("consul catalog frontend rule"),
}
provider.setupFrontEndTemplate()
testCases := []struct {
desc string
service serviceUpdate
@@ -71,6 +63,14 @@ func TestConsulCatalogGetFrontendRule(t *testing.T) {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
provider := &CatalogProvider{
Domain: "localhost",
Prefix: "traefik",
FrontEndRule: "Host:{{.ServiceName}}.{{.Domain}}",
frontEndRuleTemplate: template.New("consul catalog frontend rule"),
}
provider.setupFrontEndTemplate()
actual := provider.getFrontendRule(test.service)
assert.Equal(t, test.expected, actual)
})

View File

@@ -433,9 +433,9 @@ func (p *Provider) getServicePriority(container dockerData, serviceName string)
// Extract backend from labels for a given service and a given docker container
func (p *Provider) getServiceBackend(container dockerData, serviceName string) string {
if value, ok := getContainerServiceLabel(container, serviceName, "frontend.backend"); ok {
return container.ServiceName + "-" + value
return provider.Normalize(container.ServiceName + "-" + value)
}
return strings.TrimPrefix(container.ServiceName, "/") + "-" + p.getBackend(container) + "-" + provider.Normalize(serviceName)
return provider.Normalize(container.ServiceName + "-" + p.getBackend(container) + "-" + serviceName)
}
// Extract rule from labels for a given service and a given docker container
@@ -835,8 +835,12 @@ func listContainers(ctx context.Context, dockerClient client.ContainerAPIClient)
if err != nil {
log.Warnf("Failed to inspect container %s, error: %s", container.ID, err)
} else {
dockerData := parseContainer(containerInspected)
containersInspected = append(containersInspected, dockerData)
// This condition is here to avoid to have empty IP https://github.com/containous/traefik/issues/2459
// We register only container which are running
if containerInspected.ContainerJSONBase != nil && containerInspected.ContainerJSONBase.State != nil && containerInspected.ContainerJSONBase.State.Running {
dockerData := parseContainer(containerInspected)
containersInspected = append(containersInspected, dockerData)
}
}
}
return containersInspected, nil

View File

@@ -173,12 +173,22 @@ func TestDockerGetServiceBackend(t *testing.T) {
container: containerJSON(name("foo")),
expected: "foo-foo-myservice",
},
{
container: containerJSON(name("foo.bar")),
expected: "foo-bar-foo-bar-myservice",
},
{
container: containerJSON(labels(map[string]string{
types.LabelBackend: "another-backend",
})),
expected: "fake-another-backend-myservice",
},
{
container: containerJSON(labels(map[string]string{
types.LabelBackend: "another.backend",
})),
expected: "fake-another-backend-myservice",
},
{
container: containerJSON(labels(map[string]string{
"traefik.myservice.frontend.backend": "custom-backend",

View File

@@ -325,13 +325,13 @@ func getRuleForPath(pa v1beta1.HTTPIngressPath, i *v1beta1.Ingress) string {
ruleType = ruleTypePathPrefix
}
rule := ruleType + ":" + pa.Path
rules := []string{ruleType + ":" + pa.Path}
if rewriteTarget := i.Annotations[annotationKubernetesRewriteTarget]; rewriteTarget != "" {
rule = ruleTypeReplacePath + ":" + rewriteTarget
rules = append(rules, ruleTypeReplacePath+":"+rewriteTarget)
}
return rule
return strings.Join(rules, ";")
}
func (p *Provider) getPriority(path v1beta1.HTTPIngressPath, i *v1beta1.Ingress) int {

View File

@@ -1728,7 +1728,7 @@ func TestIngressAnnotations(t *testing.T) {
PassHostHeader: true,
Routes: map[string]types.Route{
"/api": {
Rule: "ReplacePath:/",
Rule: "PathPrefix:/api;ReplacePath:/",
},
"rewrite": {
Rule: "Host:rewrite",

View File

@@ -1,4 +1,5 @@
mkdocs==0.16.3
pymdown-extensions>=1.4
mkdocs-bootswatch>=0.4.0
pymdown-extensions==4.12
mkdocs-bootswatch==0.4.0
mkdocs-material==1.12.2
markdown==2.6.11

View File

@@ -315,22 +315,29 @@ func (f *websocketForwarder) serveHTTP(w http.ResponseWriter, req *http.Request,
defer targetConn.Close()
errc := make(chan error, 2)
replicate := func(dst io.Writer, src io.Reader) {
_, err := io.Copy(dst, src)
replicateWebsocketConn := func(dst, src *websocket.Conn, dstName, srcName string) {
var err error
for {
msgType, msg, err := src.ReadMessage()
if err != nil {
ctx.log.Errorf("vulcand/oxy/forward/websocket: Error when copying from %s to %s using ReadMessage: %v", srcName, dstName, err)
break
}
err = dst.WriteMessage(msgType, msg)
if err != nil {
ctx.log.Errorf("vulcand/oxy/forward/websocket: Error when copying from %s to %s using WriteMessage: %v", srcName, dstName, err)
break
} else {
ctx.log.Infof("vulcand/oxy/forward/websocket: Copying from %s to %s completed without error.", srcName, dstName)
}
}
errc <- err
}
go replicate(targetConn.UnderlyingConn(), underlyingConn.UnderlyingConn())
go replicateWebsocketConn(underlyingConn, targetConn, "client", "backend")
go replicateWebsocketConn(targetConn, underlyingConn, "backend", "client")
// Try to read the first message
t, msg, err := targetConn.ReadMessage()
if err != nil {
ctx.log.Errorf("Couldn't read first message : %v", err)
} else {
underlyingConn.WriteMessage(t, msg)
}
go replicate(underlyingConn.UnderlyingConn(), targetConn.UnderlyingConn())
<-errc
}

View File

@@ -132,7 +132,7 @@ func RemoveHeaders(headers http.Header, names ...string) {
}
// Parse the MIME media type value of a header.
func GetHeaderMediaType(headers http.Header, name string) (string, error) {
func GetHeaderMediaType(headers http.Header, name string) (string, error) {
mediatype, _, err := mime.ParseMediaType(headers.Get(name))
return mediatype, err
}