mirror of https://github.com/docker/docs.git
Merge pull request #509 from vieux/nodes-discovery-gen
Proposal: implement IP generator for nodes and file discoveries by @chanwit
This commit is contained in:
commit
45fc0c9272
|
|
@ -149,6 +149,27 @@ $ docker -H <swarm_ip:swarm_port> logs ...
|
|||
...
|
||||
```
|
||||
|
||||
### Range pattern for IP addresses
|
||||
|
||||
The `file` and `nodes` discoveries support a range pattern to specify IP addresses, i.e., `10.0.0.[10:200]` will be a list of nodes starting from `10.0.0.10` to `10.0.0.200`.
|
||||
|
||||
For example,
|
||||
|
||||
```bash
|
||||
# file example
|
||||
$ echo "10.0.0.[11:100]:2375" >> /tmp/my_cluster
|
||||
$ echo "10.0.1.[15:20]:2375" >> /tmp/my_cluster
|
||||
$ echo "192.168.1.2:[2:20]375" >> /tmp/my_cluster
|
||||
|
||||
# start the manager
|
||||
$ swarm manage -H tcp://<swarm_ip:swarm_port> file:///tmp/my_cluster
|
||||
```
|
||||
|
||||
```bash
|
||||
# nodes example
|
||||
$ swarm manage -H <swarm_ip:swarm_port> "nodes://10.0.0.[10:200]:2375,10.0.1.[2:250]:2375"
|
||||
```
|
||||
|
||||
## Contributing a new discovery backend
|
||||
|
||||
Contributing a new discovery backend is easy,
|
||||
|
|
|
|||
|
|
@ -23,13 +23,22 @@ func (s *FileDiscoveryService) Initialize(path string, heartbeat int) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func parseFileContent(content []byte) []string {
|
||||
result := make([]string, 0)
|
||||
for _, line := range strings.Split(strings.TrimSpace(string(content)), "\n") {
|
||||
for _, ip := range discovery.Generate(line) {
|
||||
result = append(result, ip)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (s *FileDiscoveryService) Fetch() ([]*discovery.Entry, error) {
|
||||
data, err := ioutil.ReadFile(s.path)
|
||||
fileContent, err := ioutil.ReadFile(s.path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return discovery.CreateEntries(strings.Split(string(data), "\n"))
|
||||
return discovery.CreateEntries(parseFileContent(fileContent))
|
||||
}
|
||||
|
||||
func (s *FileDiscoveryService) Watch(callback discovery.WatchCallback) {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,19 @@ func TestInitialize(t *testing.T) {
|
|||
assert.Equal(t, discovery.path, "/path/to/file")
|
||||
}
|
||||
|
||||
func TestContent(t *testing.T) {
|
||||
data := `
|
||||
1.1.1.[1:2]:1111
|
||||
2.2.2.[2:4]:2222
|
||||
`
|
||||
ips := parseFileContent([]byte(data))
|
||||
assert.Equal(t, ips[0], "1.1.1.1:1111")
|
||||
assert.Equal(t, ips[1], "1.1.1.2:1111")
|
||||
assert.Equal(t, ips[2], "2.2.2.2:2222")
|
||||
assert.Equal(t, ips[3], "2.2.2.3:2222")
|
||||
assert.Equal(t, ips[4], "2.2.2.4:2222")
|
||||
}
|
||||
|
||||
func TestRegister(t *testing.T) {
|
||||
discovery := &FileDiscoveryService{path: "/path/to/file"}
|
||||
assert.Error(t, discovery.Register("0.0.0.0"))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
package discovery
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
//
|
||||
// IP generator
|
||||
//
|
||||
func Generate(pattern string) []string {
|
||||
re, _ := regexp.Compile(`\[(.+):(.+)\]`)
|
||||
submatch := re.FindStringSubmatch(pattern)
|
||||
if submatch == nil {
|
||||
return []string{pattern}
|
||||
}
|
||||
|
||||
from, err := strconv.Atoi(submatch[1])
|
||||
if err != nil {
|
||||
return []string{pattern}
|
||||
}
|
||||
to, err := strconv.Atoi(submatch[2])
|
||||
if err != nil {
|
||||
return []string{pattern}
|
||||
}
|
||||
|
||||
template := re.ReplaceAllString(pattern, "%d")
|
||||
|
||||
result := make([]string, 0)
|
||||
for val := from; val <= to; val++ {
|
||||
entry := fmt.Sprintf(template, val)
|
||||
result = append(result, entry)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package discovery
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGeneratorNotGenerate(t *testing.T) {
|
||||
ips := Generate("127.0.0.1")
|
||||
assert.Equal(t, len(ips), 1)
|
||||
assert.Equal(t, ips[0], "127.0.0.1")
|
||||
}
|
||||
|
||||
func TestGeneratorWithPortNotGenerate(t *testing.T) {
|
||||
ips := Generate("127.0.0.1:8080")
|
||||
assert.Equal(t, len(ips), 1)
|
||||
assert.Equal(t, ips[0], "127.0.0.1:8080")
|
||||
}
|
||||
|
||||
func TestGeneratorMatchFailedNotGenerate(t *testing.T) {
|
||||
ips := Generate("127.0.0.[1]")
|
||||
assert.Equal(t, len(ips), 1)
|
||||
assert.Equal(t, ips[0], "127.0.0.[1]")
|
||||
}
|
||||
|
||||
func TestGeneratorWithPort(t *testing.T) {
|
||||
ips := Generate("127.0.0.[1:11]:2375")
|
||||
assert.Equal(t, len(ips), 11)
|
||||
assert.Equal(t, ips[0], "127.0.0.1:2375")
|
||||
assert.Equal(t, ips[1], "127.0.0.2:2375")
|
||||
assert.Equal(t, ips[2], "127.0.0.3:2375")
|
||||
assert.Equal(t, ips[3], "127.0.0.4:2375")
|
||||
assert.Equal(t, ips[4], "127.0.0.5:2375")
|
||||
assert.Equal(t, ips[5], "127.0.0.6:2375")
|
||||
assert.Equal(t, ips[6], "127.0.0.7:2375")
|
||||
assert.Equal(t, ips[7], "127.0.0.8:2375")
|
||||
assert.Equal(t, ips[8], "127.0.0.9:2375")
|
||||
assert.Equal(t, ips[9], "127.0.0.10:2375")
|
||||
assert.Equal(t, ips[10], "127.0.0.11:2375")
|
||||
}
|
||||
|
|
@ -15,13 +15,15 @@ func init() {
|
|||
}
|
||||
|
||||
func (s *NodesDiscoveryService) Initialize(uris string, _ int) error {
|
||||
for _, ip := range strings.Split(uris, ",") {
|
||||
for _, input := range strings.Split(uris, ",") {
|
||||
for _, ip := range discovery.Generate(input) {
|
||||
entry, err := discovery.NewEntry(ip)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.entries = append(s.entries, entry)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,17 @@ func TestInitialise(t *testing.T) {
|
|||
assert.Equal(t, discovery.entries[1].String(), "2.2.2.2:2222")
|
||||
}
|
||||
|
||||
func TestInitialiseWithPattern(t *testing.T) {
|
||||
discovery := &NodesDiscoveryService{}
|
||||
discovery.Initialize("1.1.1.[1:2]:1111,2.2.2.[2:4]:2222", 0)
|
||||
assert.Equal(t, len(discovery.entries), 5)
|
||||
assert.Equal(t, discovery.entries[0].String(), "1.1.1.1:1111")
|
||||
assert.Equal(t, discovery.entries[1].String(), "1.1.1.2:1111")
|
||||
assert.Equal(t, discovery.entries[2].String(), "2.2.2.2:2222")
|
||||
assert.Equal(t, discovery.entries[3].String(), "2.2.2.3:2222")
|
||||
assert.Equal(t, discovery.entries[4].String(), "2.2.2.4:2222")
|
||||
}
|
||||
|
||||
func TestRegister(t *testing.T) {
|
||||
discovery := &NodesDiscoveryService{}
|
||||
assert.Error(t, discovery.Register("0.0.0.0"))
|
||||
|
|
|
|||
Loading…
Reference in New Issue