1
0
Fork 0

feat: custom label shorthands

This commit is contained in:
Arthur K. 2025-06-11 18:07:39 +03:00
parent 585158380f
commit 0c2d49f5f4
Signed by: wzray
GPG key ID: B97F30FDC4636357
9 changed files with 152 additions and 16 deletions

View file

@ -273,6 +273,10 @@ THIS FILE MUST NOT BE EDITED BY HAND
| <a id="opt-providers-docker-endpoint" href="#opt-providers-docker-endpoint" title="#opt-providers-docker-endpoint">providers.docker.endpoint</a> | Docker server endpoint. Can be a TCP or a Unix socket endpoint. | unix:///var/run/docker.sock |
| <a id="opt-providers-docker-exposedbydefault" href="#opt-providers-docker-exposedbydefault" title="#opt-providers-docker-exposedbydefault">providers.docker.exposedbydefault</a> | Expose containers by default. | true |
| <a id="opt-providers-docker-httpclienttimeout" href="#opt-providers-docker-httpclienttimeout" title="#opt-providers-docker-httpclienttimeout">providers.docker.httpclienttimeout</a> | Client timeout for HTTP connections. | 0 |
| <a id="opt-providers-docker-labelmap" href="#opt-providers-docker-labelmap" title="#opt-providers-docker-labelmap">providers.docker.labelmap</a> | Label shorthands. | |
| <a id="opt-providers-docker-labelmap0-from" href="#opt-providers-docker-labelmap0-from" title="#opt-providers-docker-labelmap0-from">providers.docker.labelmap[0].from</a> | Shorthand label. | |
| <a id="opt-providers-docker-labelmap0-to" href="#opt-providers-docker-labelmap0-to" title="#opt-providers-docker-labelmap0-to">providers.docker.labelmap[0].to</a> | Full label with templates. | |
| <a id="opt-providers-docker-labelmap0-value" href="#opt-providers-docker-labelmap0-value" title="#opt-providers-docker-labelmap0-value">providers.docker.labelmap[0].value</a> | Optional override; used instead of user input if set. | |
| <a id="opt-providers-docker-network" href="#opt-providers-docker-network" title="#opt-providers-docker-network">providers.docker.network</a> | Default Docker network used. | |
| <a id="opt-providers-docker-password" href="#opt-providers-docker-password" title="#opt-providers-docker-password">providers.docker.password</a> | Password for Basic HTTP authentication. | |
| <a id="opt-providers-docker-tls-ca" href="#opt-providers-docker-tls-ca" title="#opt-providers-docker-tls-ca">providers.docker.tls.ca</a> | TLS CA | |
@ -422,6 +426,10 @@ THIS FILE MUST NOT BE EDITED BY HAND
| <a id="opt-providers-swarm-endpoint" href="#opt-providers-swarm-endpoint" title="#opt-providers-swarm-endpoint">providers.swarm.endpoint</a> | Docker server endpoint. Can be a TCP or a Unix socket endpoint. | unix:///var/run/docker.sock |
| <a id="opt-providers-swarm-exposedbydefault" href="#opt-providers-swarm-exposedbydefault" title="#opt-providers-swarm-exposedbydefault">providers.swarm.exposedbydefault</a> | Expose containers by default. | true |
| <a id="opt-providers-swarm-httpclienttimeout" href="#opt-providers-swarm-httpclienttimeout" title="#opt-providers-swarm-httpclienttimeout">providers.swarm.httpclienttimeout</a> | Client timeout for HTTP connections. | 0 |
| <a id="opt-providers-swarm-labelmap" href="#opt-providers-swarm-labelmap" title="#opt-providers-swarm-labelmap">providers.swarm.labelmap</a> | Label shorthands. | |
| <a id="opt-providers-swarm-labelmap0-from" href="#opt-providers-swarm-labelmap0-from" title="#opt-providers-swarm-labelmap0-from">providers.swarm.labelmap[0].from</a> | Shorthand label. | |
| <a id="opt-providers-swarm-labelmap0-to" href="#opt-providers-swarm-labelmap0-to" title="#opt-providers-swarm-labelmap0-to">providers.swarm.labelmap[0].to</a> | Full label with templates. | |
| <a id="opt-providers-swarm-labelmap0-value" href="#opt-providers-swarm-labelmap0-value" title="#opt-providers-swarm-labelmap0-value">providers.swarm.labelmap[0].value</a> | Optional override; used instead of user input if set. | |
| <a id="opt-providers-swarm-network" href="#opt-providers-swarm-network" title="#opt-providers-swarm-network">providers.swarm.network</a> | Default Docker network used. | |
| <a id="opt-providers-swarm-password" href="#opt-providers-swarm-password" title="#opt-providers-swarm-password">providers.swarm.password</a> | Password for Basic HTTP authentication. | |
| <a id="opt-providers-swarm-refreshseconds" href="#opt-providers-swarm-refreshseconds" title="#opt-providers-swarm-refreshseconds">providers.swarm.refreshseconds</a> | Polling interval for swarm mode. | 15 |

View file

@ -798,6 +798,18 @@ Expose containers by default. (Default: ```true```)
`--providers.docker.httpclienttimeout`:
Client timeout for HTTP connections. (Default: ```0```)
`--providers.docker.labelmap`:
Label shorthands.
`--providers.docker.labelmap[n].from`:
Shorthand label.
`--providers.docker.labelmap[n].to`:
Full label with templates.
`--providers.docker.labelmap[n].value`:
Optional override; used instead of user input if set.
`--providers.docker.network`:
Default Docker network used.
@ -1245,6 +1257,18 @@ Expose containers by default. (Default: ```true```)
`--providers.swarm.httpclienttimeout`:
Client timeout for HTTP connections. (Default: ```0```)
`--providers.swarm.labelmap`:
Label shorthands.
`--providers.swarm.labelmap[n].from`:
Shorthand label.
`--providers.swarm.labelmap[n].to`:
Full label with templates.
`--providers.swarm.labelmap[n].value`:
Optional override; used instead of user input if set.
`--providers.swarm.network`:
Default Docker network used.

View file

@ -798,6 +798,18 @@ Expose containers by default. (Default: ```true```)
`TRAEFIK_PROVIDERS_DOCKER_HTTPCLIENTTIMEOUT`:
Client timeout for HTTP connections. (Default: ```0```)
`TRAEFIK_PROVIDERS_DOCKER_LABELMAP`:
Label shorthands.
`TRAEFIK_PROVIDERS_DOCKER_LABELMAP_n_FROM`:
Shorthand label.
`TRAEFIK_PROVIDERS_DOCKER_LABELMAP_n_TO`:
Full label with templates.
`TRAEFIK_PROVIDERS_DOCKER_LABELMAP_n_VALUE`:
Optional override; used instead of user input if set.
`TRAEFIK_PROVIDERS_DOCKER_NETWORK`:
Default Docker network used.
@ -1245,6 +1257,18 @@ Expose containers by default. (Default: ```true```)
`TRAEFIK_PROVIDERS_SWARM_HTTPCLIENTTIMEOUT`:
Client timeout for HTTP connections. (Default: ```0```)
`TRAEFIK_PROVIDERS_SWARM_LABELMAP`:
Label shorthands.
`TRAEFIK_PROVIDERS_SWARM_LABELMAP_n_FROM`:
Shorthand label.
`TRAEFIK_PROVIDERS_SWARM_LABELMAP_n_TO`:
Full label with templates.
`TRAEFIK_PROVIDERS_SWARM_LABELMAP_n_VALUE`:
Optional override; used instead of user input if set.
`TRAEFIK_PROVIDERS_SWARM_NETWORK`:
Default Docker network used.

View file

@ -99,6 +99,16 @@
password = "foobar"
endpoint = "foobar"
httpClientTimeout = "42s"
[[providers.docker.labelMap]]
from = "foobar"
to = "foobar"
value = "foobar"
[[providers.docker.labelMap]]
from = "foobar"
to = "foobar"
value = "foobar"
[providers.docker.tls]
ca = "foobar"
cert = "foobar"
@ -117,6 +127,16 @@
endpoint = "foobar"
httpClientTimeout = "42s"
refreshSeconds = "42s"
[[providers.swarm.labelMap]]
from = "foobar"
to = "foobar"
value = "foobar"
[[providers.swarm.labelMap]]
from = "foobar"
to = "foobar"
value = "foobar"
[providers.swarm.tls]
ca = "foobar"
cert = "foobar"

View file

@ -110,6 +110,13 @@ providers:
useBindPortIP: true
watch: true
defaultRule: foobar
labelMap:
- from: foobar
to: foobar
value: foobar
- from: foobar
to: foobar
value: foobar
username: foobar
password: foobar
endpoint: foobar
@ -127,6 +134,13 @@ providers:
useBindPortIP: true
watch: true
defaultRule: foobar
labelMap:
- from: foobar
to: foobar
value: foobar
- from: foobar
to: foobar
value: foobar
username: foobar
password: foobar
endpoint: foobar

View file

@ -396,8 +396,8 @@ func AddStore(configuration *dynamic.TLSConfiguration, storeName string, store t
return reflect.DeepEqual(configuration.Stores[storeName], store)
}
// MakeDefaultRuleTemplate creates the default rule template.
func MakeDefaultRuleTemplate(defaultRule string, funcMap template.FuncMap) (*template.Template, error) {
// MakeAnyTemplate creates a template with any name
func MakeAnyTemplate(name string, value string, funcMap template.FuncMap) (*template.Template, error) {
defaultFuncMap := sprig.TxtFuncMap()
defaultFuncMap["normalize"] = Normalize
@ -405,7 +405,12 @@ func MakeDefaultRuleTemplate(defaultRule string, funcMap template.FuncMap) (*tem
defaultFuncMap[k] = fn
}
return template.New("defaultRule").Funcs(defaultFuncMap).Parse(defaultRule)
return template.New(name).Funcs(defaultFuncMap).Parse(value)
}
// MakeDefaultRuleTemplate creates the default rule template.
func MakeDefaultRuleTemplate(defaultRule string, funcMap template.FuncMap) (*template.Template, error) {
return MakeAnyTemplate("defaultRule", defaultRule, funcMap)
}
// BuildTCPRouterConfiguration builds a router configuration.

View file

@ -1,6 +1,7 @@
package docker
import (
"bytes"
"context"
"errors"
"fmt"
@ -28,15 +29,50 @@ func NewDynConfBuilder(configuration Shared, apiClient client.APIClient, swarm b
return &DynConfBuilder{Shared: configuration, apiClient: apiClient, swarm: swarm}
}
func (p *DynConfBuilder) applyLabels(container *dockerData, model interface{}) {
for _, item := range p.LabelMap {
value, ok := container.Labels[item.From]
if !ok { // label doesn't exist
continue
}
writer := &bytes.Buffer{}
if err := item.toTpl.Execute(writer, model); err != nil {
continue // should never happen?
}
to := writer.String()
if item.Value != nil {
container.Labels[to] = *item.Value
} else {
container.Labels[to] = value
}
}
}
func (p *DynConfBuilder) build(ctx context.Context, containersInspected []dockerData) *dynamic.Configuration {
configurations := make(map[string]*dynamic.Configuration)
for _, container := range containersInspected {
serviceName := getServiceName(container)
model := struct {
Name string
ContainerName string
Labels *map[string]string
}{
Name: serviceName,
ContainerName: strings.TrimPrefix(container.Name, "/"),
Labels: &container.Labels,
}
containerName := getServiceName(container) + "-" + container.ID
logger := log.Ctx(ctx).With().Str("container", containerName).Logger()
ctxContainer := logger.WithContext(ctx)
p.applyLabels(&container, model)
if !p.keepContainer(ctxContainer, container) {
continue
}
@ -83,18 +119,6 @@ func (p *DynConfBuilder) build(ctx context.Context, containersInspected []docker
continue
}
serviceName := getServiceName(container)
model := struct {
Name string
ContainerName string
Labels map[string]string
}{
Name: serviceName,
ContainerName: strings.TrimPrefix(container.Name, "/"),
Labels: container.Labels,
}
provider.BuildRouterConfiguration(ctx, confFromLabel.HTTP, serviceName, p.defaultRuleTpl, model)
configurations[containerName] = confFromLabel

View file

@ -48,8 +48,15 @@ func (p *Provider) Init() error {
if err != nil {
return fmt.Errorf("error while parsing default rule: %w", err)
}
p.defaultRuleTpl = defaultRuleTpl
for _, item := range p.LabelMap {
toTpl, err := provider.MakeAnyTemplate(item.From, item.To, nil)
if err != nil {
return fmt.Errorf("error while parsing label %v: %w", item.To, err)
}
item.toTpl = toTpl
}
return nil
}

View file

@ -33,9 +33,19 @@ type Shared struct {
Watch bool `description:"Watch Docker events." json:"watch,omitempty" toml:"watch,omitempty" yaml:"watch,omitempty" export:"true"`
DefaultRule string `description:"Default rule." json:"defaultRule,omitempty" toml:"defaultRule,omitempty" yaml:"defaultRule,omitempty"`
LabelMap []*LabelMapItem `description:"Label shorthands." json:"labelMap,omitempty" toml:"labelMap,omitempty" yaml:"labelMap,omitempty"`
defaultRuleTpl *template.Template
}
type LabelMapItem struct {
From string `description:"Shorthand label." json:"from,omitempty" toml:"from,omitempty" yaml:"from,omitempty"`
To string `description:"Full label with templates." json:"to,omitempty" toml:"to,omitempty" yaml:"to,omitempty"`
Value *string `description:"Optional override; used instead of user input if set." json:"value,omitempty" toml:"value,omitempty" yaml:"value,omitempty"`
toTpl *template.Template
}
func inspectContainers(ctx context.Context, dockerClient client.ContainerAPIClient, containerID string) dockerData {
containerInspected, err := dockerClient.ContainerInspect(ctx, containerID)
if err != nil {