Skip to content

Commit

Permalink
feat(consul,service_tags): Support escaped comma (#401)
Browse files Browse the repository at this point in the history
* feat(service_tags): Support escaped comma
* test(bridge): Adds test for escaped comma in tags + fix types_test.go tests
  • Loading branch information
samber authored and mattatcha committed Jan 20, 2017
1 parent 990786d commit 1a1a9ae
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 3 deletions.
3 changes: 3 additions & 0 deletions bridge/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ func (f *fakeAdapter) Deregister(service *Service) error {
func (f *fakeAdapter) Refresh(service *Service) error {
return nil
}
func (f *fakeAdapter) Services() ([]*Service, error) {
return nil, nil
}
30 changes: 27 additions & 3 deletions bridge/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,36 @@ func mapDefault(m map[string]string, key, default_ string) string {
return v
}

// Golang regexp module does not support /(?!\\),/ syntax for spliting by not escaped comma
// Then this function is reproducing it
func recParseEscapedComma(str string) []string {
if len(str) == 0 {
return []string{}
} else if str[0] == ',' {
return recParseEscapedComma(str[1:])
}

offset := 0
for len(str[offset:]) > 0 {
index := strings.Index(str[offset:], ",")

if index == -1 {
break
} else if str[offset+index-1:offset+index] != "\\" {
return append(recParseEscapedComma(str[offset+index+1:]), str[:offset+index])
}

str = str[:offset+index-1] + str[offset+index:]
offset += index
}

return []string{str}
}

func combineTags(tagParts ...string) []string {
tags := make([]string, 0)
for _, element := range tagParts {
if element != "" {
tags = append(tags, strings.Split(element, ",")...)
}
tags = append(tags, recParseEscapedComma(element)...)
}
return tags
}
Expand Down
59 changes: 59 additions & 0 deletions bridge/util_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package bridge

import (
"sort"
"testing"

"github.com/stretchr/testify/assert"
)

func TestEscapedComma(t *testing.T) {
cases := []struct {
Tag string
Expected []string
}{
{
Tag: "",
Expected: []string{},
},
{
Tag: "foobar",
Expected: []string{"foobar"},
},
{
Tag: "foo,bar",
Expected: []string{"foo", "bar"},
},
{
Tag: "foo\\,bar",
Expected: []string{"foo,bar"},
},
{
Tag: "foo,bar\\,baz",
Expected: []string{"foo", "bar,baz"},
},
{
Tag: "\\,foobar\\,",
Expected: []string{",foobar,"},
},
{
Tag: ",,,,foo,,,bar,,,",
Expected: []string{"foo", "bar"},
},
{
Tag: ",,,,",
Expected: []string{},
},
{
Tag: ",,\\,,",
Expected: []string{","},
},
}

for _, c := range cases {
results := recParseEscapedComma(c.Tag)
sort.Strings(c.Expected)
sort.Strings(results)
assert.EqualValues(t, c.Expected, results)
}
}
7 changes: 7 additions & 0 deletions docs/user/services.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,13 @@ Results in `Service`:

Keep in mind not all of the `Service` object may be used by the registry backend. For example, currently none of them support registering arbitrary attributes. This field is there for future use.

The comma can be escaped by adding a backslash, such as the following example:

$ docker run -d --name redis.0 -p 10000:6379 \
-e "SERVICE_NAME=db" \
-e "SERVICE_TAGS=/(;\\,:-_)/" \
-e "SERVICE_REGION=us2" progrium/redis

### Multiple services with defaults

$ docker run -d --name nginx.0 -p 4443:443 -p 8000:80 progrium/nginx
Expand Down

0 comments on commit 1a1a9ae

Please sign in to comment.