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
-}
... ...
@@ -179,51 +179,6 @@ func getConfigFile(filename string) (*composetypes.ConfigFile, error) {
179 179
 	}, nil
180 180
 }
181 181
 
182
-func convertNetworks(
183
-	namespace namespace,
184
-	networks map[string]composetypes.NetworkConfig,
185
-) (map[string]types.NetworkCreate, []string) {
186
-	if networks == nil {
187
-		networks = make(map[string]composetypes.NetworkConfig)
188
-	}
189
-
190
-	// TODO: only add default network if it's used
191
-	networks["default"] = composetypes.NetworkConfig{}
192
-
193
-	externalNetworks := []string{}
194
-	result := make(map[string]types.NetworkCreate)
195
-
196
-	for internalName, network := range networks {
197
-		if network.External.External {
198
-			externalNetworks = append(externalNetworks, network.External.Name)
199
-			continue
200
-		}
201
-
202
-		createOpts := types.NetworkCreate{
203
-			Labels:  getStackLabels(namespace.name, network.Labels),
204
-			Driver:  network.Driver,
205
-			Options: network.DriverOpts,
206
-		}
207
-
208
-		if network.Ipam.Driver != "" || len(network.Ipam.Config) > 0 {
209
-			createOpts.IPAM = &networktypes.IPAM{}
210
-		}
211
-
212
-		if network.Ipam.Driver != "" {
213
-			createOpts.IPAM.Driver = network.Ipam.Driver
214
-		}
215
-		for _, ipamConfig := range network.Ipam.Config {
216
-			config := networktypes.IPAMConfig{
217
-				Subnet: ipamConfig.Subnet,
218
-			}
219
-			createOpts.IPAM.Config = append(createOpts.IPAM.Config, config)
220
-		}
221
-		result[internalName] = createOpts
222
-	}
223
-
224
-	return result, externalNetworks
225
-}
226
-
227 182
 func validateExternalNetworks(
228 183
 	ctx context.Context,
229 184
 	dockerCli *command.DockerCli,
230 185
new file mode 100644
... ...
@@ -0,0 +1,75 @@
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(namespace Namespace, networks networks) (map[string]types.NetworkCreate, []string) {
35
+	if networks == nil {
36
+		networks = make(map[string]composetypes.NetworkConfig)
37
+	}
38
+
39
+	// TODO: only add default network if it's used
40
+	networks["default"] = composetypes.NetworkConfig{}
41
+
42
+	externalNetworks := []string{}
43
+	result := make(map[string]types.NetworkCreate)
44
+
45
+	for internalName, network := range networks {
46
+		if network.External.External {
47
+			externalNetworks = append(externalNetworks, network.External.Name)
48
+			continue
49
+		}
50
+
51
+		createOpts := types.NetworkCreate{
52
+			Labels:  AddStackLabel(namespace, network.Labels),
53
+			Driver:  network.Driver,
54
+			Options: network.DriverOpts,
55
+		}
56
+
57
+		if network.Ipam.Driver != "" || len(network.Ipam.Config) > 0 {
58
+			createOpts.IPAM = &networktypes.IPAM{}
59
+		}
60
+
61
+		if network.Ipam.Driver != "" {
62
+			createOpts.IPAM.Driver = network.Ipam.Driver
63
+		}
64
+		for _, ipamConfig := range network.Ipam.Config {
65
+			config := networktypes.IPAMConfig{
66
+				Subnet: ipamConfig.Subnet,
67
+			}
68
+			createOpts.IPAM.Config = append(createOpts.IPAM.Config, config)
69
+		}
70
+		result[internalName] = createOpts
71
+	}
72
+
73
+	return result, externalNetworks
74
+}
0 75
new file mode 100644
... ...
@@ -0,0 +1,85 @@
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
+	networks, externals := ConvertNetworks(namespace, source)
82
+	assert.DeepEqual(t, networks, expected)
83
+	assert.DeepEqual(t, externals, []string{"special"})
84
+}
... ...
@@ -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