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

docker.network resource #477

Merged
merged 14 commits into from Nov 9, 2016
8 changes: 8 additions & 0 deletions docs/content/resources/docker.container.md
Expand Up @@ -79,6 +79,14 @@ specified, "tcp" is assumed

list of DNS servers for the container to use

- `network_mode` (string)

the mode of the container network. default: default

- `networks` (list of strings)

the networks to connect the container to

- `volumes` (list of strings)

bind mounts volumes
Expand Down
105 changes: 105 additions & 0 deletions docs/content/resources/docker.network.md
@@ -0,0 +1,105 @@
---
title: "docker.network"
slug: "docker-network"
date: "2016-11-04T08:35:32-04:00"
menu:
main:
parent: resources
---


Network is responsible for managing Docker networks. It assumes that there is
already a Docker daemon running on the system.


## Example

```hcl
docker.network "test-network" {
name = "test-network"
state = "present"
force = true

labels {
environment = "test"
}

options {
"com.docker.network.bridge.enable_icc" = "true"
}

internal = false
ipv6 = false
ipam_driver = "default"

ipam_config {
subnet = "192.168.129.0/24"
gateway = "192.168.129.1"

aux_addresses {
router = "192.168.129.40"
printer = "192.168.129.41"
}
}
}

```


## Parameters

- `name` (required string)

name of the network

- `driver` (string)

network driver. default: bridge

- `labels` (map of string to string)

labels to set on the network

- `options` (map of string to anything)

driver specific options

- `ipam_driver` (string)

ip address management driver. default: default

- `ipam_config` (list of ipamConfigMaps)

optional custom IPAM configuration. multiple IPAM configurations are
permitted. Each IPAM configuration block should contain one or more of the
following items:

* subnet: subnet in CIDR format
* gateway: ipv4 or ipv6 gateway for the corresponding subnet
* ip_range: container ips are allocated from this sub-ranges (CIDR format)
* aux_address: auxiliary ipv4 or ipv6 addresses used by the network driver.
Aux addresses are specified as a map with a name key and an IP
address value

- `internal` (bool)

restricts external access to the network

- `ipv6` (bool)

enable ipv6 networking

- `state` (State)


Valid values: `present` and `absent`

indicates whether the network should exist. default: present

- `force` (bool)

indicates whether or not the network will be recreated if the state is not
what is expected. By default, the module will only check to see if the
network exists. Specified as a boolean value


1 change: 1 addition & 0 deletions docs/sources.csv
@@ -1,6 +1,7 @@
docker.container,../resource/docker/container/preparer.go,../samples/dockerContainer.hcl,Preparer
docker.image,../resource/docker/image/preparer.go,../samples/dockerImage.hcl,Preparer
docker.volume,../resource/docker/volume/preparer.go,../samples/dockerVolume.hcl,Preparer
docker.network,../resource/docker/network/preparer.go,../samples/dockerNetwork.hcl,Preparer
file.content,../resource/file/content/preparer.go,../samples/fileContent.hcl,Preparer
file.directory,../resource/file/directory/preparer.go,../samples/fileDirectory.hcl,Preparer
file.mode,../resource/file/mode/preparer.go,../samples/fileMode.hcl,Preparer
Expand Down
1 change: 1 addition & 0 deletions load/resource.go
Expand Up @@ -28,6 +28,7 @@ import (
// import empty to register types for SetResources
_ "github.com/asteris-llc/converge/resource/docker/container"
_ "github.com/asteris-llc/converge/resource/docker/image"
_ "github.com/asteris-llc/converge/resource/docker/network"
_ "github.com/asteris-llc/converge/resource/docker/volume"
_ "github.com/asteris-llc/converge/resource/file/content"
_ "github.com/asteris-llc/converge/resource/file/directory"
Expand Down
55 changes: 54 additions & 1 deletion resource/docker/container/container.go
Expand Up @@ -32,10 +32,16 @@ import (
const (
containerStatusRunning = "running"
containerStatusCreated = "created"

// DefaultNetworkMode is the mode of the container network
DefaultNetworkMode = "default"
)

// these variable names can be injected by the docker engine
var engineEnvVars = []string{"https_proxy", "http_proxy", "no_proxy", "ftp_proxy"}
var (
engineEnvVars = []string{"https_proxy", "http_proxy", "no_proxy", "ftp_proxy"}
builtinNetworks = []string{"default", "bridge", "host", "none", "container"}
)

// Container is responsible for creating docker containers
type Container struct {
Expand All @@ -54,6 +60,8 @@ type Container struct {
Volumes []string
VolumesFrom []string
PublishAllPorts bool
NetworkMode string
Networks []string
CStatus string
Force bool
client docker.APIClient
Expand Down Expand Up @@ -105,6 +113,7 @@ func (c *Container) Apply(context.Context) (resource.TaskStatus, error) {
PortBindings: toPortBindingMap(c.PortBindings),
Binds: binds,
VolumesFrom: c.VolumesFrom,
NetworkMode: c.NetworkMode,
}

opts := dc.CreateContainerOptions{
Expand All @@ -118,6 +127,13 @@ func (c *Container) Apply(context.Context) (resource.TaskStatus, error) {
return c, err
}

for _, name := range c.Networks {
err = c.client.ConnectNetwork(name, container)
if err != nil {
return c, err
}
}

if c.CStatus == "" || c.CStatus == containerStatusRunning {
err = c.client.StartContainer(c.Name, container.ID)
if err != nil {
Expand Down Expand Up @@ -156,6 +172,12 @@ func (c *Container) diffContainer(container *dc.Container, status *resource.Stat
strings.Join(container.HostConfig.VolumesFrom, ", "),
strings.Join(c.VolumesFrom, ", "),
"")
status.AddDifference(
"network_mode",
container.HostConfig.NetworkMode,
c.NetworkMode,
DefaultNetworkMode,
)
}

image, err := c.client.FindImage(container.Image)
Expand Down Expand Up @@ -216,13 +238,44 @@ func (c *Container) diffContainer(container *dc.Container, status *resource.Stat
actual, expected = c.compareBinds(container)
status.AddDifference("binds", actual, expected, "")

// Networks
actual, expected = c.compareNetworks(container)
status.AddDifference("networks", actual, expected, "")

// Image
existingRepoTag := preferredRepoTag(c.Image, image)
status.AddDifference("image", existingRepoTag, c.Image, "")

return nil
}

func (c *Container) compareNetworks(container *dc.Container) (actual, expected string) {
if container.NetworkSettings == nil {
return "", ""
}

var containerNetworks []string
for name := range container.NetworkSettings.Networks {
var isBuiltin bool
for _, builtin := range builtinNetworks {
if strings.EqualFold(name, builtin) {
isBuiltin = true
break
}
}
if !isBuiltin {
containerNetworks = append(containerNetworks, name)
}
}
sort.Strings(containerNetworks)

expectedNetworks := make([]string, len(c.Networks))
copy(expectedNetworks, c.Networks)
sort.Strings(expectedNetworks)

return strings.Join(containerNetworks, ", "), strings.Join(expectedNetworks, ", ")
}

func (c *Container) compareEnv(container *dc.Container, image *dc.Image) (actual, expected string) {
varName := func(envvar string) string {
return strings.ToLower(strings.Split(envvar, "=")[0])
Expand Down