feat(consul,service_tags): Support escaped comma (#401)

* feat(service_tags): Support escaped comma
* test(bridge): Adds test for escaped comma in tags + fix types_test.go tests
This commit is contained in:
Samuel BERTHE 2017-01-20 18:24:30 +01:00 committed by Matt Aitchison
parent 990786db28
commit 1a1a9ae684
4 changed files with 96 additions and 3 deletions

View File

@ -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
}

View File

@ -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
}

59
bridge/util_test.go Normal file
View File

@ -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)
}
}

View File

@ -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