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

Support "." in map keys #7654

Merged
merged 3 commits into from
Jul 15, 2016
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
66 changes: 50 additions & 16 deletions builtin/providers/triton/resource_machine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,8 @@ func TestAccTritonMachine_metadata(t *testing.T) {
machineName := fmt.Sprintf("acctest-%d", acctest.RandInt())
basic := fmt.Sprintf(testAccTritonMachine_metadata_1, machineName)
add_metadata := fmt.Sprintf(testAccTritonMachine_metadata_1, machineName)
add_metadata_2 := fmt.Sprintf(testAccTritonMachine_metadata_2, machineName)
add_metadata_3 := fmt.Sprintf(testAccTritonMachine_metadata_3, machineName)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Expand All @@ -283,15 +285,29 @@ func TestAccTritonMachine_metadata(t *testing.T) {
"triton_machine.test", "user_data", "hello"),
),
},
resource.TestStep{
Config: add_metadata_2,
Check: resource.ComposeTestCheckFunc(
testCheckTritonMachineExists("triton_machine.test"),
resource.TestCheckResourceAttr(
"triton_machine.test",
"tags.triton.cns.services", "test-cns-service"),
),
},
resource.TestStep{
Config: add_metadata_3,
Check: resource.ComposeTestCheckFunc(
testCheckTritonMachineExists("triton_machine.test"),
resource.TestCheckResourceAttr(
"triton_machine.test",
"tags.triton.cns.services", "test-cns-service"),
),
},
},
})
}

var testAccTritonMachine_basic = `
provider "triton" {
url = "https://us-west-1.api.joyentcloud.com"
}

resource "triton_machine" "test" {
name = "%s"
package = "g4-general-4G"
Expand All @@ -304,10 +320,6 @@ resource "triton_machine" "test" {
`

var testAccTritonMachine_firewall_0 = `
provider "triton" {
url = "https://us-west-1.api.joyentcloud.com"
}

resource "triton_machine" "test" {
name = "%s"
package = "g4-general-4G"
Expand All @@ -317,10 +329,6 @@ resource "triton_machine" "test" {
}
`
var testAccTritonMachine_firewall_1 = `
provider "triton" {
url = "https://us-west-1.api.joyentcloud.com"
}

resource "triton_machine" "test" {
name = "%s"
package = "g4-general-4G"
Expand All @@ -331,10 +339,6 @@ resource "triton_machine" "test" {
`

var testAccTritonMachine_metadata_1 = `
provider "triton" {
url = "https://us-west-1.api.joyentcloud.com"
}

resource "triton_machine" "test" {
name = "%s"
package = "g4-general-4G"
Expand All @@ -347,7 +351,37 @@ resource "triton_machine" "test" {
}
}
`
var testAccTritonMachine_metadata_2 = `
variable "tags" {
default = {
test = "hello!"
triton.cns.services = "test-cns-service"
}
}
resource "triton_machine" "test" {
name = "%s"
package = "g4-highcpu-128M"
image = "c20b4b7c-e1a6-11e5-9a4d-ef590901732e"

user_data = "hello"

tags = "${var.tags}"
}
`
var testAccTritonMachine_metadata_3 = `
resource "triton_machine" "test" {
name = "%s"
package = "g4-highcpu-128M"
image = "c20b4b7c-e1a6-11e5-9a4d-ef590901732e"

user_data = "hello"

tags = {
test = "hello!"
triton.cns.services = "test-cns-service"
}
}
`
var testAccTritonMachine_withnic = `
resource "triton_fabric" "test" {
name = "%s-network"
Expand Down
30 changes: 21 additions & 9 deletions terraform/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,6 @@ type Resource struct {
// its a primary instance, a tainted instance, or an orphan.
type ResourceFlag byte

const (
FlagPrimary ResourceFlag = 1 << iota
FlagTainted
FlagOrphan
FlagReplacePrimary
FlagDeposed
)

// InstanceInfo is used to hold information about the instance and/or
// resource being modified.
type InstanceInfo struct {
Expand Down Expand Up @@ -180,20 +172,32 @@ func (c *ResourceConfig) get(
}

var current interface{} = raw
for _, part := range parts {
var previous interface{} = nil
for i, part := range parts {
if current == nil {
return nil, false
}

cv := reflect.ValueOf(current)
switch cv.Kind() {
case reflect.Map:
previous = current
v := cv.MapIndex(reflect.ValueOf(part))
if !v.IsValid() {
if i > 0 && i != (len(parts)-1) {
tryKey := strings.Join(parts[i:], ".")
v := cv.MapIndex(reflect.ValueOf(tryKey))
if !v.IsValid() {
return nil, false
}
return v.Interface(), true
}

return nil, false
}
current = v.Interface()
case reflect.Slice:
previous = current
if part == "#" {
current = cv.Len()
} else {
Expand All @@ -206,6 +210,14 @@ func (c *ResourceConfig) get(
}
current = cv.Index(int(i)).Interface()
}
case reflect.String:
// This happens when map keys contain "." and have a common
// prefix so were split as path components above.
actualKey := strings.Join(parts[i-1:], ".")
if prevMap, ok := previous.(map[string]interface{}); ok {
return prevMap[actualKey], true
}
return nil, false
default:
panic(fmt.Sprintf("Unknown kind: %s", cv.Kind()))
}
Expand Down