secret and network cleanup

This commit is contained in:
Xander Flood 2019-11-12 17:41:59 -05:00
parent e391230447
commit 5babf5fb17
6 changed files with 224 additions and 18 deletions

View file

@ -1,9 +1,12 @@
package docker
import (
"fmt"
"strings"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
)
func labelToPair(label map[string]interface{}) (string, string) {
@ -56,6 +59,22 @@ var labelSchema = &schema.Resource{
},
}
//unfortunately, _one_ of the several place that the old label schema was
//used specified that the keys had to be strings, while the others allowed
//any type of key and coerced them into strings.
func upgradeLabelMapFromV0ToV1(labelMap map[string]interface{}) []map[string]string {
var migratedState []map[string]string
for l, v := range labelMap {
migratedState = append(migratedState, map[string]string{
"label": l,
"value": fmt.Sprintf("%v", v),
})
}
return migratedState
}
//gatherImmediateSubkeys given an incomplete attribute identifier, find all
//the strings (if any) that appear after this one in the various dot-separated
//identifiers.
@ -87,3 +106,22 @@ func getLabelMapForPartialKey(attrs map[string]string, partialKey string) map[st
return labelMap
}
func testCheckLabelMap(name string, partialKey string, expectedLabels map[string]string) resource.TestCheckFunc {
return func(s *terraform.State) error {
attrs := s.RootModule().Resources[name].Primary.Attributes
labelMap := getLabelMapForPartialKey(attrs, partialKey)
if len(labelMap) != len(expectedLabels) {
return fmt.Errorf("expected %v labels, found %v", len(expectedLabels), len(labelMap))
}
for l, v := range expectedLabels {
if labelMap[l] != v {
return fmt.Errorf("expected value %v for label %v, got %v", v, l, labelMap[v])
}
}
return nil
}
}

View file

@ -15,6 +15,130 @@ func resourceDockerNetwork() *schema.Resource {
Read: resourceDockerNetworkRead,
Delete: resourceDockerNetworkDelete,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"labels": {
Type: schema.TypeSet,
Optional: true,
ForceNew: true,
Elem: labelSchema,
},
"check_duplicate": {
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
},
"driver": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
},
"options": {
Type: schema.TypeMap,
Optional: true,
ForceNew: true,
Computed: true,
},
"internal": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
ForceNew: true,
},
"attachable": {
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
},
"ingress": {
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
},
"ipv6": {
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
},
"ipam_driver": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"ipam_config": {
Type: schema.TypeSet,
Optional: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"subnet": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"ip_range": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"gateway": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"aux_address": {
Type: schema.TypeMap,
Optional: true,
ForceNew: true,
},
},
},
Set: resourceDockerIpamConfigHash,
},
"scope": {
Type: schema.TypeString,
Computed: true,
},
},
SchemaVersion: 1,
StateUpgraders: []schema.StateUpgrader{
{
Version: 0,
Type: resourceDockerNetworkV0().CoreConfigSchema().ImpliedType(),
Upgrade: func(rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) {
labelMap := rawState["labels"].(map[string]interface{})
rawState["labels"] = upgradeLabelMapFromV0ToV1(labelMap)
return rawState, nil
},
},
},
}
}
func resourceDockerNetworkV0() *schema.Resource {
return &schema.Resource{
//This is only used for state migration, so the CRUD
//callbacks are no longer relevant
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,

View file

@ -20,7 +20,7 @@ func resourceDockerNetworkCreate(d *schema.ResourceData, meta interface{}) error
createOpts := types.NetworkCreate{}
if v, ok := d.GetOk("labels"); ok {
createOpts.Labels = mapTypeMapValsToString(v.(map[string]interface{}))
createOpts.Labels = labelSetToMap(v.(*schema.Set))
}
if v, ok := d.GetOk("check_duplicate"); ok {
createOpts.CheckDuplicate = v.(bool)

View file

@ -5,6 +5,7 @@ import (
"testing"
"context"
"github.com/docker/docker/api/types"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
@ -260,8 +261,12 @@ func TestAccDockerNetwork_labels(t *testing.T) {
Config: testAccDockerNetworkLabelsConfig,
Check: resource.ComposeTestCheckFunc(
testAccNetwork("docker_network.foo", &n),
testAccNetworkLabel(&n, "com.docker.compose.network", "foo"),
testAccNetworkLabel(&n, "com.docker.compose.project", "test"),
testCheckLabelMap("docker_network.foo", "labels",
map[string]string{
"com.docker.compose.network": "foo",
"com.docker.compose.project": "test",
},
),
),
},
},
@ -280,9 +285,13 @@ func testAccNetworkLabel(network *types.NetworkResource, name string, value stri
const testAccDockerNetworkLabelsConfig = `
resource "docker_network" "foo" {
name = "test_foo"
labels = {
"com.docker.compose.network" = "foo"
"com.docker.compose.project" = "test"
labels {
label = "com.docker.compose.network"
value = "foo"
}
labels {
label = "com.docker.compose.project"
value = "test"
}
}
`

View file

@ -40,6 +40,49 @@ func resourceDockerSecret() *schema.Resource {
Elem: labelSchema,
},
},
SchemaVersion: 1,
StateUpgraders: []schema.StateUpgrader{
{
Version: 0,
Type: resourceDockerSecretV0().CoreConfigSchema().ImpliedType(),
Upgrade: func(rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) {
labelMap := rawState["labels"].(map[string]interface{})
rawState["labels"] = upgradeLabelMapFromV0ToV1(labelMap)
return rawState, nil
},
},
},
}
}
func resourceDockerSecretV0() *schema.Resource {
return &schema.Resource{
//This is only used for state migration, so the CRUD
//callbacks are no longer relevant
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Description: "User-defined name of the secret",
Required: true,
ForceNew: true,
},
"data": {
Type: schema.TypeString,
Description: "User-defined name of the secret",
Required: true,
Sensitive: true,
ForceNew: true,
ValidateFunc: validateStringIsBase64Encoded(),
},
"labels": {
Type: schema.TypeMap,
Optional: true,
ForceNew: true,
},
},
}
}

View file

@ -95,18 +95,10 @@ func TestAccDockerSecret_labels(t *testing.T) {
}
}
`,
Check: resource.ComposeTestCheckFunc(
func(s *terraform.State) error {
attrs := s.RootModule().Resources["docker_secret.foo"].Primary.Attributes
labelMap := getLabelMapForPartialKey(attrs, "labels")
if len(labelMap) != 2 ||
labelMap["test1"] != "foo" ||
labelMap["test2"] != "bar" {
return fmt.Errorf("label map had unexpected structure: %v", labelMap)
}
return nil
Check: testCheckLabelMap("docker_secret.foo", "labels",
map[string]string{
"test1": "foo",
"test2": "bar",
},
),
},