Skip to content

Commit

Permalink
Add support for Go template to -tags flag
Browse files Browse the repository at this point in the history
  • Loading branch information
psyhomb committed Nov 20, 2020
1 parent 4322fe0 commit 6e79fff
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 6 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v7
v7.3.1
135 changes: 131 additions & 4 deletions bridge/bridge.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package bridge

import (
"bytes"
"errors"
"log"
"net"
Expand All @@ -11,6 +12,7 @@ import (
"strconv"
"strings"
"sync"
"text/template"

dockerapi "github.com/fsouza/go-dockerclient"
)
Expand Down Expand Up @@ -202,7 +204,7 @@ func (b *Bridge) add(containerId string, quiet bool) {

// Extract configured host port mappings, relevant when using --net=host
for port, _ := range container.Config.ExposedPorts {
published := []dockerapi.PortBinding{ {"0.0.0.0", port.Port()}, }
published := []dockerapi.PortBinding{{"0.0.0.0", port.Port()}}
ports[string(port)] = servicePort(container, port, published)
}

Expand Down Expand Up @@ -309,7 +311,7 @@ func (b *Bridge) newService(port ServicePort, isgroup bool) *Service {
service.IP = containerIp
}
log.Println("using container IP " + service.IP + " from label '" +
b.config.UseIpFromLabel + "'")
b.config.UseIpFromLabel + "'")
} else {
log.Println("Label '" + b.config.UseIpFromLabel +
"' not found in container configuration")
Expand All @@ -332,13 +334,138 @@ func (b *Bridge) newService(port ServicePort, isgroup bool) *Service {
}
}

// Use container inspect data to populate tags list
// https://github.com/fsouza/go-dockerclient/blob/master/container.go#L441-L483
ForceTags := b.config.ForceTags
if len(ForceTags) != 0 {
// Template functions
fm := template.FuncMap{
// Slice function
"slice": func(v string, i ...int) string {
if len(i) == 1 {
if len(v) >= i[0] {
return v[i[0]:]
}
}

if len(i) == 2 {
if len(v) >= i[0] && len(v) >= i[1] {
if i[0] == 0 {
return v[:i[1]]
}
if i[1] < i[0] {
return v[i[0]:]
}
return v[i[0]:i[1]]
}
}

return v
},
// sIndex function
"sIndex": func(s []string, i int) string {
if i < 0 {
i = i * -1
if i >= len(s) {
return s[0]
}
return s[len(s)-i]
}

if i >= len(s) {
return s[len(s)-1]
}

return s[i]
},
// mIndex function
"mIndex": func(m map[string]string, k string) string {
return m[k]
},
// toUpper function
"toUpper": func(v string) string {
return strings.ToUpper(v)
},
// toLower function
"toLower": func(v string) string {
return strings.ToLower(v)
},
// join function
"join": func(s []string, sep string) string {
return strings.Join(s, sep)
},
// split function
"split": func(v, sep string) []string {
return strings.Split(v, sep)
},
// splitIndex function
"splitIndex": func(v, sep string, i int) string {
l := strings.Split(v, sep)

if i < 0 {
i = i * -1
if i >= len(l) {
return l[0]
}
return l[len(l)-i]
}

if i >= len(l) {
return l[len(l)-1]
}

return l[i]
},
// matchFirstElement function
"matchFirstElement": func(s []string, r string) string {
var m string

re := regexp.MustCompile(r)
for _, e := range s {
if re.MatchString(e) {
m = e
break
}
}

return m
},
// matchAllElements function
"matchAllElements": func(s []string, r string) []string {
var m []string

re := regexp.MustCompile(r)
for _, e := range s {
if re.MatchString(e) {
m = append(m, e)
}
}

return m
},
}

tmpl, err := template.New("tags").Funcs(fm).Parse(ForceTags)
if err != nil {
log.Fatalf("%s template parsing failed with error: %s", ForceTags, err)
}

var b bytes.Buffer
err = tmpl.Execute(&b, container)
if err != nil {
log.Fatalf("%s template execution failed with error: %s", ForceTags, err)
}

ForceTags = b.String()
}

if port.PortType == "udp" {
service.Tags = combineTags(
mapDefault(metadata, "tags", ""), b.config.ForceTags, "udp")
mapDefault(metadata, "tags", ""), ForceTags, "udp")
service.ID = service.ID + ":udp"
} else {
service.Tags = combineTags(
mapDefault(metadata, "tags", ""), b.config.ForceTags)
mapDefault(metadata, "tags", ""), ForceTags)
}

id := mapDefault(metadata, "id", "")
Expand Down
2 changes: 1 addition & 1 deletion registrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ var explicit = flag.Bool("explicit", false, "Only register containers which have
var useIpFromLabel = flag.String("useIpFromLabel", "", "Use IP which is stored in a label assigned to the container")
var refreshInterval = flag.Int("ttl-refresh", 0, "Frequency with which service TTLs are refreshed")
var refreshTtl = flag.Int("ttl", 0, "TTL for services (default is no expiry)")
var forceTags = flag.String("tags", "", "Append tags for all registered services")
var forceTags = flag.String("tags", "", "Append tags for all registered services (supports Go template)")
var resyncInterval = flag.Int("resync", 0, "Frequency with which services are resynchronized")
var deregister = flag.String("deregister", "always", "Deregister exited services \"always\" or \"on-success\"")
var retryAttempts = flag.Int("retry-attempts", 0, "Max retry attempts to establish a connection with the backend. Use -1 for infinite retries")
Expand Down

0 comments on commit 6e79fff

Please sign in to comment.