Browse code

Move ConvertNetworks to composetransform package.

Signed-off-by: Daniel Nephin <dnephin@docker.com>

Daniel Nephin authored on 2016/12/01 05:33:54
Showing 5 changed files
... ...
@@ -9,18 +9,6 @@ import (
9 9
 	"github.com/docker/docker/client"
10 10
 )
11 11
 
12
-const (
13
-	labelNamespace = "com.docker.stack.namespace"
14
-)
15
-
16
-func getStackLabels(namespace string, labels map[string]string) map[string]string {
17
-	if labels == nil {
18
-		labels = make(map[string]string)
19
-	}
20
-	labels[labelNamespace] = namespace
21
-	return labels
22
-}
23
-
24 12
 func getStackFilter(namespace string) filters.Args {
25 13
 	filter := filters.NewArgs()
26 14
 	filter.Add("label", labelNamespace+"="+namespace)
... ...
@@ -46,11 +34,3 @@ func getStackNetworks(
46 46
 		ctx,
47 47
 		types.NetworkListOptions{Filters: getStackFilter(namespace)})
48 48
 }
49
-
50
-type namespace struct {
51
-	name string
52
-}
53
-
54
-func (n namespace) scope(name string) string {
55
-	return n.name + "_" + name
56
-}
... ...
@@ -192,50 +192,6 @@ func getConfigFile(filename string) (*composetypes.ConfigFile, error) {
192 192
 	}, nil
193 193
 }
194 194
 
195
-func convertNetworks(
196
-	namespace namespace,
197
-	networks map[string]composetypes.NetworkConfig,
198
-	servicesNetworks map[string]struct{},
199
-) (map[string]types.NetworkCreate, []string) {
200
-	if networks == nil {
201
-		networks = make(map[string]composetypes.NetworkConfig)
202
-	}
203
-
204
-	externalNetworks := []string{}
205
-	result := make(map[string]types.NetworkCreate)
206
-
207
-	for internalName := range servicesNetworks {
208
-		network := networks[internalName]
209
-		if network.External.External {
210
-			externalNetworks = append(externalNetworks, network.External.Name)
211
-			continue
212
-		}
213
-
214
-		createOpts := types.NetworkCreate{
215
-			Labels:  getStackLabels(namespace.name, network.Labels),
216
-			Driver:  network.Driver,
217
-			Options: network.DriverOpts,
218
-		}
219
-
220
-		if network.Ipam.Driver != "" || len(network.Ipam.Config) > 0 {
221
-			createOpts.IPAM = &networktypes.IPAM{}
222
-		}
223
-
224
-		if network.Ipam.Driver != "" {
225
-			createOpts.IPAM.Driver = network.Ipam.Driver
226
-		}
227
-		for _, ipamConfig := range network.Ipam.Config {
228
-			config := networktypes.IPAMConfig{
229
-				Subnet: ipamConfig.Subnet,
230
-			}
231
-			createOpts.IPAM.Config = append(createOpts.IPAM.Config, config)
232
-		}
233
-		result[internalName] = createOpts
234
-	}
235
-
236
-	return result, externalNetworks
237
-}
238
-
239 195
 func validateExternalNetworks(
240 196
 	ctx context.Context,
241 197
 	dockerCli *command.DockerCli,
242 198
new file mode 100644
... ...
@@ -0,0 +1,77 @@
0
+package composetransform
1
+
2
+import (
3
+	composetypes "github.com/aanand/compose-file/types"
4
+	"github.com/docker/docker/api/types"
5
+	networktypes "github.com/docker/docker/api/types/network"
6
+)
7
+
8
+const (
9
+	labelNamespace = "com.docker.stack.namespace"
10
+)
11
+
12
+// Namespace mangles names by prepending the name
13
+type Namespace struct {
14
+	name string
15
+}
16
+
17
+// Scope prepends the namespace to a name
18
+func (n Namespace) Scope(name string) string {
19
+	return n.name + "_" + name
20
+}
21
+
22
+// AddStackLabel returns labels with the namespace label added
23
+func AddStackLabel(namespace Namespace, labels map[string]string) map[string]string {
24
+	if labels == nil {
25
+		labels = make(map[string]string)
26
+	}
27
+	labels[labelNamespace] = namespace.name
28
+	return labels
29
+}
30
+
31
+type networks map[string]composetypes.NetworkConfig
32
+
33
+// ConvertNetworks from the compose-file type to the engine API type
34
+func ConvertNetworks(
35
+	namespace Namespace,
36
+	networks networks,
37
+	servicesNetworks map[string]struct{},
38
+) (map[string]types.NetworkCreate, []string) {
39
+	if networks == nil {
40
+		networks = make(map[string]composetypes.NetworkConfig)
41
+	}
42
+
43
+	externalNetworks := []string{}
44
+	result := make(map[string]types.NetworkCreate)
45
+
46
+	for internalName := range servicesNetworks {
47
+		network := networks[internalName]
48
+		if network.External.External {
49
+			externalNetworks = append(externalNetworks, network.External.Name)
50
+			continue
51
+		}
52
+
53
+		createOpts := types.NetworkCreate{
54
+			Labels:  AddStackLabel(namespace, network.Labels),
55
+			Driver:  network.Driver,
56
+			Options: network.DriverOpts,
57
+		}
58
+
59
+		if network.Ipam.Driver != "" || len(network.Ipam.Config) > 0 {
60
+			createOpts.IPAM = &networktypes.IPAM{}
61
+		}
62
+
63
+		if network.Ipam.Driver != "" {
64
+			createOpts.IPAM.Driver = network.Ipam.Driver
65
+		}
66
+		for _, ipamConfig := range network.Ipam.Config {
67
+			config := networktypes.IPAMConfig{
68
+				Subnet: ipamConfig.Subnet,
69
+			}
70
+			createOpts.IPAM.Config = append(createOpts.IPAM.Config, config)
71
+		}
72
+		result[internalName] = createOpts
73
+	}
74
+
75
+	return result, externalNetworks
76
+}
0 77
new file mode 100644
... ...
@@ -0,0 +1,90 @@
0
+package composetransform
1
+
2
+import (
3
+	"testing"
4
+
5
+	composetypes "github.com/aanand/compose-file/types"
6
+	"github.com/docker/docker/api/types"
7
+	"github.com/docker/docker/api/types/network"
8
+	"github.com/docker/docker/pkg/testutil/assert"
9
+)
10
+
11
+func TestNamespaceScope(t *testing.T) {
12
+	scoped := Namespace{name: "foo"}.Scope("bar")
13
+	assert.Equal(t, scoped, "foo_bar")
14
+}
15
+
16
+func TestAddStackLabel(t *testing.T) {
17
+	labels := map[string]string{
18
+		"something": "labeled",
19
+	}
20
+	actual := AddStackLabel(Namespace{name: "foo"}, labels)
21
+	expected := map[string]string{
22
+		"something":    "labeled",
23
+		labelNamespace: "foo",
24
+	}
25
+	assert.DeepEqual(t, actual, expected)
26
+}
27
+
28
+func TestConvertNetworks(t *testing.T) {
29
+	namespace := Namespace{name: "foo"}
30
+	source := networks{
31
+		"normal": composetypes.NetworkConfig{
32
+			Driver: "overlay",
33
+			DriverOpts: map[string]string{
34
+				"opt": "value",
35
+			},
36
+			Ipam: composetypes.IPAMConfig{
37
+				Driver: "driver",
38
+				Config: []*composetypes.IPAMPool{
39
+					{
40
+						Subnet: "10.0.0.0",
41
+					},
42
+				},
43
+			},
44
+			Labels: map[string]string{
45
+				"something": "labeled",
46
+			},
47
+		},
48
+		"outside": composetypes.NetworkConfig{
49
+			External: composetypes.External{
50
+				External: true,
51
+				Name:     "special",
52
+			},
53
+		},
54
+	}
55
+	expected := map[string]types.NetworkCreate{
56
+		"default": {
57
+			Labels: map[string]string{
58
+				labelNamespace: "foo",
59
+			},
60
+		},
61
+		"normal": {
62
+			Driver: "overlay",
63
+			IPAM: &network.IPAM{
64
+				Driver: "driver",
65
+				Config: []network.IPAMConfig{
66
+					{
67
+						Subnet: "10.0.0.0",
68
+					},
69
+				},
70
+			},
71
+			Options: map[string]string{
72
+				"opt": "value",
73
+			},
74
+			Labels: map[string]string{
75
+				labelNamespace: "foo",
76
+				"something":    "labeled",
77
+			},
78
+		},
79
+	}
80
+
81
+	serviceNetworks := map[string]struct{}{
82
+		"default": {},
83
+		"normal":  {},
84
+		"outside": {},
85
+	}
86
+	networks, externals := ConvertNetworks(namespace, source, serviceNetworks)
87
+	assert.DeepEqual(t, networks, expected)
88
+	assert.DeepEqual(t, externals, []string{"special"})
89
+}
... ...
@@ -7,6 +7,8 @@ import (
7 7
 	"reflect"
8 8
 	"runtime"
9 9
 	"strings"
10
+
11
+	"github.com/davecgh/go-spew/spew"
10 12
 )
11 13
 
12 14
 // TestingT is an interface which defines the methods of testing.T that are
... ...
@@ -49,7 +51,8 @@ func NilError(t TestingT, err error) {
49 49
 // they are not "deeply equal".
50 50
 func DeepEqual(t TestingT, actual, expected interface{}) {
51 51
 	if !reflect.DeepEqual(actual, expected) {
52
-		fatal(t, "Expected '%v' (%T) got '%v' (%T)", expected, expected, actual, actual)
52
+		fatal(t, "Expected (%T):\n%v\n\ngot (%T):\n%s\n",
53
+			expected, spew.Sdump(expected), actual, spew.Sdump(actual))
53 54
 	}
54 55
 }
55 56