Skip to content
This repository has been archived by the owner on Dec 11, 2020. It is now read-only.

Add labels to support docker stacks #92

Merged
merged 8 commits into from
Oct 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions docker/resource_docker_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,9 +398,10 @@ func resourceDockerContainer() *schema.Resource {
},

"network_mode": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validateStringMatchesPattern(`^(bridge|host|none|container:.+|service:.+)$`),
},

"networks": &schema.Schema{
Expand Down
4 changes: 4 additions & 0 deletions docker/resource_docker_container_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,10 @@ func resourceDockerContainerCreate(d *schema.ResourceData, meta interface{}) err
endpointConfig.Aliases = stringSetToStringSlice(v.(*schema.Set))
}

if err := client.NetworkDisconnect(context.Background(), "bridge", retContainer.ID, false); err != nil {
return fmt.Errorf("Unable to disconnect the default network: %s", err)
}

for _, rawNetwork := range v.(*schema.Set).List() {
networkID := rawNetwork.(string)
if err := client.NetworkConnect(context.Background(), networkID, retContainer.ID, endpointConfig); err != nil {
Expand Down
24 changes: 24 additions & 0 deletions docker/resource_docker_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ func resourceDockerNetwork() *schema.Resource {
ForceNew: true,
},

"labels": &schema.Schema{
Type: schema.TypeMap,
Optional: true,
ForceNew: true,
},

"check_duplicate": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Expand Down Expand Up @@ -49,6 +55,24 @@ func resourceDockerNetwork() *schema.Resource {
ForceNew: true,
},

"attachable": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
},

"ingress": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
},

"ipv6": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
},

"ipam_driver": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Expand Down
15 changes: 15 additions & 0 deletions docker/resource_docker_network_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ func resourceDockerNetworkCreate(d *schema.ResourceData, meta interface{}) error
client := meta.(*ProviderConfig).DockerClient

createOpts := types.NetworkCreate{}
if v, ok := d.GetOk("labels"); ok {
createOpts.Labels = mapTypeMapValsToString(v.(map[string]interface{}))
}
if v, ok := d.GetOk("check_duplicate"); ok {
createOpts.CheckDuplicate = v.(bool)
}
Expand All @@ -29,6 +32,15 @@ func resourceDockerNetworkCreate(d *schema.ResourceData, meta interface{}) error
if v, ok := d.GetOk("internal"); ok {
createOpts.Internal = v.(bool)
}
if v, ok := d.GetOk("attachable"); ok {
createOpts.Attachable = v.(bool)
}
if v, ok := d.GetOk("ingress"); ok {
createOpts.Ingress = v.(bool)
}
if v, ok := d.GetOk("ipv6"); ok {
createOpts.EnableIPv6 = v.(bool)
}

ipamOpts := &network.IPAM{}
ipamOptsSet := false
Expand Down Expand Up @@ -128,6 +140,9 @@ func resourceDockerNetworkReadRefreshFunc(
log.Printf("[DEBUG] Docker network inspect: %s", jsonObj)

d.Set("internal", retNetwork.Internal)
d.Set("attachable", retNetwork.Attachable)
d.Set("ingress", retNetwork.Ingress)
d.Set("ipv6", retNetwork.EnableIPv6)
d.Set("driver", retNetwork.Driver)
d.Set("scope", retNetwork.Scope)
if retNetwork.Scope == "overlay" {
Expand Down
74 changes: 73 additions & 1 deletion docker/resource_docker_network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,78 @@ func testAccNetworkInternal(network *types.NetworkResource, internal bool) resou
const testAccDockerNetworkInternalConfig = `
resource "docker_network" "foobar" {
name = "foobar"
internal = "true"
internal = true
}
`

func TestAccDockerNetwork_attachable(t *testing.T) {
var n types.NetworkResource

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccDockerNetworkAttachableConfig,
Check: resource.ComposeTestCheckFunc(
testAccNetwork("docker_network.foobar", &n),
testAccNetworkAttachable(&n, true),
),
},
},
})
}

func testAccNetworkAttachable(network *types.NetworkResource, attachable bool) resource.TestCheckFunc {
return func(s *terraform.State) error {
if network.Attachable != attachable {
return fmt.Errorf("Bad value for attribute 'attachable': %t", network.Attachable)
}
return nil
}
}

const testAccDockerNetworkAttachableConfig = `
resource "docker_network" "foobar" {
name = "foobar"
attachable = true
}
`

func TestAccDockerNetwork_labels(t *testing.T) {
var n types.NetworkResource

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccDockerNetworkLabelsConfig,
Check: resource.ComposeTestCheckFunc(
testAccNetwork("docker_network.foobar", &n),
testAccNetworkLabel(&n, "com.docker.compose.network", "foobar"),
testAccNetworkLabel(&n, "com.docker.compose.project", "test"),
),
},
},
})
}

func testAccNetworkLabel(network *types.NetworkResource, name string, value string) resource.TestCheckFunc {
return func(s *terraform.State) error {
if network.Labels[name] != value {
return fmt.Errorf("Bad value for label '%s': %s", name, network.Labels[name])
}
return nil
}
}

const testAccDockerNetworkLabelsConfig = `
resource "docker_network" "foobar" {
name = "test_foobar"
labels {
"com.docker.compose.network" = "foobar"
"com.docker.compose.project" = "test"
}
}
`
10 changes: 10 additions & 0 deletions docker/resource_docker_secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ func resourceDockerSecret() *schema.Resource {
ForceNew: true,
ValidateFunc: validateStringIsBase64Encoded(),
},

"labels": &schema.Schema{
Type: schema.TypeMap,
Optional: true,
ForceNew: true,
},
},
}
}
Expand All @@ -46,6 +52,10 @@ func resourceDockerSecretCreate(d *schema.ResourceData, meta interface{}) error
Data: data,
}

if v, ok := d.GetOk("labels"); ok {
secretSpec.Annotations.Labels = mapTypeMapValsToString(v.(map[string]interface{}))
}

secret, err := client.SecretCreate(context.Background(), secretSpec)
if err != nil {
return err
Expand Down
27 changes: 27 additions & 0 deletions docker/resource_docker_secret_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func TestAccDockerSecret_basic(t *testing.T) {
},
})
}

func TestAccDockerSecret_basicUpdatable(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Expand Down Expand Up @@ -72,6 +73,32 @@ func TestAccDockerSecret_basicUpdatable(t *testing.T) {
})
}

func TestAccDockerSecret_labels(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckDockerSecretDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: `
resource "docker_secret" "foo" {
name = "foo-secret"
data = "Ymxhc2RzYmxhYmxhMTI0ZHNkd2VzZA=="
labels {
"test1" = "foo"
"test2" = "bar"
}
}
`,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("docker_secret.foo", "labels.test1", "foo"),
resource.TestCheckResourceAttr("docker_secret.foo", "labels.test2", "bar"),
),
},
},
})
}

/////////////
// Helpers
/////////////
Expand Down
8 changes: 8 additions & 0 deletions docker/resource_docker_volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ func resourceDockerVolume() *schema.Resource {
Computed: true,
ForceNew: true,
},
"labels": &schema.Schema{
Type: schema.TypeMap,
Optional: true,
ForceNew: true,
},
"driver": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -53,6 +58,9 @@ func resourceDockerVolumeCreate(d *schema.ResourceData, meta interface{}) error
if v, ok := d.GetOk("name"); ok {
createOpts.Name = v.(string)
}
if v, ok := d.GetOk("labels"); ok {
createOpts.Labels = mapTypeMapValsToString(v.(map[string]interface{}))
}
if v, ok := d.GetOk("driver"); ok {
createOpts.Driver = v.(string)
}
Expand Down
38 changes: 38 additions & 0 deletions docker/resource_docker_volume_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,41 @@ resource "docker_volume" "foo" {
name = "testAccDockerVolume_basic"
}
`

func TestAccDockerVolume_labels(t *testing.T) {
var v types.Volume

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccDockerVolumeLabelsConfig,
Check: resource.ComposeTestCheckFunc(
checkDockerVolume("docker_volume.foo", &v),
testAccVolumeLabel(&v, "com.docker.compose.project", "test"),
testAccVolumeLabel(&v, "com.docker.compose.volume", "foo"),
),
},
},
})
}

func testAccVolumeLabel(volume *types.Volume, name string, value string) resource.TestCheckFunc {
return func(s *terraform.State) error {
if volume.Labels[name] != value {
return fmt.Errorf("Bad value for label '%s': %s", name, volume.Labels[name])
}
return nil
}
}

const testAccDockerVolumeLabelsConfig = `
resource "docker_volume" "foo" {
name = "test_foo"
labels {
"com.docker.compose.project" = "test"
"com.docker.compose.volume" = "foo"
}
}
`
7 changes: 7 additions & 0 deletions website/docs/r/network.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ resource "docker_network" "private_network" {
The following arguments are supported:

* `name` - (Required, string) The name of the Docker network.
* `labels` - (Optional, map of string/string key/value pairs) User-defined key/value metadata.
* `check_duplicate` - (Optional, boolean) Requests daemon to check for networks
with same name.
* `driver` - (Optional, string) Name of the network driver to use. Defaults to
Expand All @@ -37,6 +38,12 @@ The following arguments are supported:
the drivers.
* `internal` - (Optional, boolean) Restrict external access to the network.
Defaults to `false`.
* `attachable` - (Optional, boolean) Enable manual container attachment to the network.
Defaults to `false`.
* `ingress` - (Optional, boolean) Create swarm routing-mesh network.
Defaults to `false`.
* `ipv6` - (Optional, boolean) Enable IPv6 networking.
Defaults to `false`.
* `ipam_driver` - (Optional, string) Driver used by the custom IP scheme of the
network.
* `ipam_config` - (Optional, block) See [IPAM config](#ipam_config) below for
Expand Down
2 changes: 1 addition & 1 deletion website/docs/r/secret.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ The following arguments are supported:

* `name` - (Required, string) The name of the Docker secret.
* `data` - (Required, string) The base64 encoded data of the secret.

* `labels` - (Optional, map of string/string key/value pairs) User-defined key/value metadata.

## Attributes Reference

Expand Down
1 change: 1 addition & 0 deletions website/docs/r/volume.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ The following arguments are supported:

* `name` - (Optional, string) The name of the Docker volume (generated if not
provided).
* `labels` - (Optional, map of string/string key/value pairs) User-defined key/value metadata.
* `driver` - (Optional, string) Driver type for the volume (defaults to local).
* `driver_opts` - (Optional, map of strings) Options specific to the driver.

Expand Down