Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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