浏览代码

Move ConvertNetworks to composetransform package.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
Daniel Nephin 8 年之前
父节点
当前提交
6b778c9633

+ 0 - 20
cli/command/stack/common.go

@@ -9,18 +9,6 @@ import (
 	"github.com/docker/docker/client"
 )
 
-const (
-	labelNamespace = "com.docker.stack.namespace"
-)
-
-func getStackLabels(namespace string, labels map[string]string) map[string]string {
-	if labels == nil {
-		labels = make(map[string]string)
-	}
-	labels[labelNamespace] = namespace
-	return labels
-}
-
 func getStackFilter(namespace string) filters.Args {
 	filter := filters.NewArgs()
 	filter.Add("label", labelNamespace+"="+namespace)
@@ -46,11 +34,3 @@ func getStackNetworks(
 		ctx,
 		types.NetworkListOptions{Filters: getStackFilter(namespace)})
 }
-
-type namespace struct {
-	name string
-}
-
-func (n namespace) scope(name string) string {
-	return n.name + "_" + name
-}

+ 0 - 45
cli/command/stack/deploy.go

@@ -179,51 +179,6 @@ func getConfigFile(filename string) (*composetypes.ConfigFile, error) {
 	}, nil
 }
 
-func convertNetworks(
-	namespace namespace,
-	networks map[string]composetypes.NetworkConfig,
-) (map[string]types.NetworkCreate, []string) {
-	if networks == nil {
-		networks = make(map[string]composetypes.NetworkConfig)
-	}
-
-	// TODO: only add default network if it's used
-	networks["default"] = composetypes.NetworkConfig{}
-
-	externalNetworks := []string{}
-	result := make(map[string]types.NetworkCreate)
-
-	for internalName, network := range networks {
-		if network.External.External {
-			externalNetworks = append(externalNetworks, network.External.Name)
-			continue
-		}
-
-		createOpts := types.NetworkCreate{
-			Labels:  getStackLabels(namespace.name, network.Labels),
-			Driver:  network.Driver,
-			Options: network.DriverOpts,
-		}
-
-		if network.Ipam.Driver != "" || len(network.Ipam.Config) > 0 {
-			createOpts.IPAM = &networktypes.IPAM{}
-		}
-
-		if network.Ipam.Driver != "" {
-			createOpts.IPAM.Driver = network.Ipam.Driver
-		}
-		for _, ipamConfig := range network.Ipam.Config {
-			config := networktypes.IPAMConfig{
-				Subnet: ipamConfig.Subnet,
-			}
-			createOpts.IPAM.Config = append(createOpts.IPAM.Config, config)
-		}
-		result[internalName] = createOpts
-	}
-
-	return result, externalNetworks
-}
-
 func validateExternalNetworks(
 	ctx context.Context,
 	dockerCli *command.DockerCli,

+ 75 - 0
pkg/composetransform/compose.go

@@ -0,0 +1,75 @@
+package composetransform
+
+import (
+	composetypes "github.com/aanand/compose-file/types"
+	"github.com/docker/docker/api/types"
+	networktypes "github.com/docker/docker/api/types/network"
+)
+
+const (
+	labelNamespace = "com.docker.stack.namespace"
+)
+
+// Namespace mangles names by prepending the name
+type Namespace struct {
+	name string
+}
+
+// Scope prepends the namespace to a name
+func (n Namespace) Scope(name string) string {
+	return n.name + "_" + name
+}
+
+// AddStackLabel returns labels with the namespace label added
+func AddStackLabel(namespace Namespace, labels map[string]string) map[string]string {
+	if labels == nil {
+		labels = make(map[string]string)
+	}
+	labels[labelNamespace] = namespace.name
+	return labels
+}
+
+type networks map[string]composetypes.NetworkConfig
+
+// ConvertNetworks from the compose-file type to the engine API type
+func ConvertNetworks(namespace Namespace, networks networks) (map[string]types.NetworkCreate, []string) {
+	if networks == nil {
+		networks = make(map[string]composetypes.NetworkConfig)
+	}
+
+	// TODO: only add default network if it's used
+	networks["default"] = composetypes.NetworkConfig{}
+
+	externalNetworks := []string{}
+	result := make(map[string]types.NetworkCreate)
+
+	for internalName, network := range networks {
+		if network.External.External {
+			externalNetworks = append(externalNetworks, network.External.Name)
+			continue
+		}
+
+		createOpts := types.NetworkCreate{
+			Labels:  AddStackLabel(namespace, network.Labels),
+			Driver:  network.Driver,
+			Options: network.DriverOpts,
+		}
+
+		if network.Ipam.Driver != "" || len(network.Ipam.Config) > 0 {
+			createOpts.IPAM = &networktypes.IPAM{}
+		}
+
+		if network.Ipam.Driver != "" {
+			createOpts.IPAM.Driver = network.Ipam.Driver
+		}
+		for _, ipamConfig := range network.Ipam.Config {
+			config := networktypes.IPAMConfig{
+				Subnet: ipamConfig.Subnet,
+			}
+			createOpts.IPAM.Config = append(createOpts.IPAM.Config, config)
+		}
+		result[internalName] = createOpts
+	}
+
+	return result, externalNetworks
+}

+ 85 - 0
pkg/composetransform/compose_test.go

@@ -0,0 +1,85 @@
+package composetransform
+
+import (
+	"testing"
+
+	composetypes "github.com/aanand/compose-file/types"
+	"github.com/docker/docker/api/types"
+	"github.com/docker/docker/api/types/network"
+	"github.com/docker/docker/pkg/testutil/assert"
+)
+
+func TestNamespaceScope(t *testing.T) {
+	scoped := Namespace{name: "foo"}.Scope("bar")
+	assert.Equal(t, scoped, "foo_bar")
+}
+
+func TestAddStackLabel(t *testing.T) {
+	labels := map[string]string{
+		"something": "labeled",
+	}
+	actual := AddStackLabel(Namespace{name: "foo"}, labels)
+	expected := map[string]string{
+		"something":    "labeled",
+		labelNamespace: "foo",
+	}
+	assert.DeepEqual(t, actual, expected)
+}
+
+func TestConvertNetworks(t *testing.T) {
+	namespace := Namespace{name: "foo"}
+	source := networks{
+		"normal": composetypes.NetworkConfig{
+			Driver: "overlay",
+			DriverOpts: map[string]string{
+				"opt": "value",
+			},
+			Ipam: composetypes.IPAMConfig{
+				Driver: "driver",
+				Config: []*composetypes.IPAMPool{
+					{
+						Subnet: "10.0.0.0",
+					},
+				},
+			},
+			Labels: map[string]string{
+				"something": "labeled",
+			},
+		},
+		"outside": composetypes.NetworkConfig{
+			External: composetypes.External{
+				External: true,
+				Name:     "special",
+			},
+		},
+	}
+	expected := map[string]types.NetworkCreate{
+		"default": {
+			Labels: map[string]string{
+				labelNamespace: "foo",
+			},
+		},
+		"normal": {
+			Driver: "overlay",
+			IPAM: &network.IPAM{
+				Driver: "driver",
+				Config: []network.IPAMConfig{
+					{
+						Subnet: "10.0.0.0",
+					},
+				},
+			},
+			Options: map[string]string{
+				"opt": "value",
+			},
+			Labels: map[string]string{
+				labelNamespace: "foo",
+				"something":    "labeled",
+			},
+		},
+	}
+
+	networks, externals := ConvertNetworks(namespace, source)
+	assert.DeepEqual(t, networks, expected)
+	assert.DeepEqual(t, externals, []string{"special"})
+}

+ 4 - 1
pkg/testutil/assert/assert.go

@@ -7,6 +7,8 @@ import (
 	"reflect"
 	"runtime"
 	"strings"
+
+	"github.com/davecgh/go-spew/spew"
 )
 
 // TestingT is an interface which defines the methods of testing.T that are
@@ -49,7 +51,8 @@ func NilError(t TestingT, err error) {
 // they are not "deeply equal".
 func DeepEqual(t TestingT, actual, expected interface{}) {
 	if !reflect.DeepEqual(actual, expected) {
-		fatal(t, "Expected '%v' (%T) got '%v' (%T)", expected, expected, actual, actual)
+		fatal(t, "Expected (%T):\n%v\n\ngot (%T):\n%s\n",
+			expected, spew.Sdump(expected), actual, spew.Sdump(actual))
 	}
 }