@ -317,19 +317,37 @@ new line
After : cty . ObjectVal ( map [ string ] cty . Value {
"id" : cty . UnknownVal ( cty . String ) ,
"password" : cty . StringVal ( "top-secret" ) ,
"conn_info" : cty . ObjectVal ( map [ string ] cty . Value {
"user" : cty . StringVal ( "not-secret" ) ,
"password" : cty . StringVal ( "top-secret" ) ,
} ) ,
} ) ,
Schema : & configschema . Block {
Attributes : map [ string ] * configschema . Attribute {
"id" : { Type : cty . String , Computed : true } ,
"password" : { Type : cty . String , Optional : true , Sensitive : true } ,
// FIXME: This is a temporary situation; once the NestedType
// specific printer is implemented this will need to be
// updated so that only the sensitive nested attribute is
// hidden.
"conn_info" : {
NestedType : & configschema . Object {
Nesting : configschema . NestingSingle ,
Attributes : map [ string ] * configschema . Attribute {
"user" : { Type : cty . String , Optional : true } ,
"password" : { Type : cty . String , Optional : true , Sensitive : true } ,
} ,
} ,
} ,
} ,
} ,
RequiredReplace : cty . NewPathSet ( ) ,
Tainted : false ,
ExpectedOutput : ` # test_instance . example will be created
+ resource "test_instance" "example" {
+ id = ( known after apply )
+ password = ( sensitive value )
+ conn_info = ( sensitive value )
+ id = ( known after apply )
+ password = ( sensitive value )
}
` ,
} ,
@ -2209,6 +2227,12 @@ func TestResourceChange_nestedList(t *testing.T) {
"volume_type" : cty . StringVal ( "gp2" ) ,
} ) ,
} ) ,
"disks" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"mount_point" : cty . StringVal ( "/var/diska" ) ,
"size" : cty . StringVal ( "50GB" ) ,
} ) ,
} ) ,
} ) ,
After : cty . ObjectVal ( map [ string ] cty . Value {
"id" : cty . StringVal ( "i-02ae66f368e8518a9" ) ,
@ -2218,33 +2242,21 @@ func TestResourceChange_nestedList(t *testing.T) {
"volume_type" : cty . StringVal ( "gp2" ) ,
} ) ,
} ) ,
"disks" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"mount_point" : cty . StringVal ( "/var/diska" ) ,
"size" : cty . StringVal ( "50GB" ) ,
} ) ,
} ) ,
} ) ,
RequiredReplace : cty . NewPathSet ( ) ,
Tainted : false ,
Schema : & configschema . Block {
Attributes : map [ string ] * configschema . Attribute {
"id" : { Type : cty . String , Optional : true , Computed : true } ,
"ami" : { Type : cty . String , Optional : true } ,
} ,
BlockTypes : map [ string ] * configschema . NestedBlock {
"root_block_device" : {
Block : configschema . Block {
Attributes : map [ string ] * configschema . Attribute {
"volume_type" : {
Type : cty . String ,
Optional : true ,
Computed : true ,
} ,
} ,
} ,
Nesting : configschema . NestingList ,
} ,
} ,
} ,
Schema : testSchemaNestingList ,
ExpectedOutput : ` # test_instance . example will be updated in - place
~ resource "test_instance" "example" {
~ ami = "ami-BEFORE" - > "ami-AFTER"
id = "i-02ae66f368e8518a9"
~ ami = "ami-BEFORE" - > "ami-AFTER"
id = "i-02ae66f368e8518a9"
# ( 1 unchanged attribute hidden )
# ( 1 unchanged block hidden )
}
@ -2259,10 +2271,18 @@ func TestResourceChange_nestedList(t *testing.T) {
"root_block_device" : cty . ListValEmpty ( cty . Object ( map [ string ] cty . Type {
"volume_type" : cty . String ,
} ) ) ,
"disks" : cty . ListValEmpty ( cty . Object ( map [ string ] cty . Type {
"mount_point" : cty . String ,
"size" : cty . String ,
} ) ) ,
} ) ,
After : cty . ObjectVal ( map [ string ] cty . Value {
"id" : cty . StringVal ( "i-02ae66f368e8518a9" ) ,
"ami" : cty . StringVal ( "ami-AFTER" ) ,
"disks" : cty . ListVal ( [ ] cty . Value { cty . ObjectVal ( map [ string ] cty . Value {
"mount_point" : cty . NullVal ( cty . String ) ,
"size" : cty . NullVal ( cty . String ) ,
} ) } ) ,
"root_block_device" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"volume_type" : cty . NullVal ( cty . String ) ,
@ -2271,30 +2291,17 @@ func TestResourceChange_nestedList(t *testing.T) {
} ) ,
RequiredReplace : cty . NewPathSet ( ) ,
Tainted : false ,
Schema : & configschema . Block {
Attributes : map [ string ] * configschema . Attribute {
"id" : { Type : cty . String , Optional : true , Computed : true } ,
"ami" : { Type : cty . String , Optional : true } ,
} ,
BlockTypes : map [ string ] * configschema . NestedBlock {
"root_block_device" : {
Block : configschema . Block {
Attributes : map [ string ] * configschema . Attribute {
"volume_type" : {
Type : cty . String ,
Optional : true ,
Computed : true ,
} ,
} ,
} ,
Nesting : configschema . NestingList ,
} ,
} ,
} ,
Schema : testSchemaNestingList ,
ExpectedOutput : ` # test_instance . example will be updated in - place
~ resource "test_instance" "example" {
~ ami = "ami-BEFORE" - > "ami-AFTER"
id = "i-02ae66f368e8518a9"
~ ami = "ami-BEFORE" - > "ami-AFTER"
~ disks = [ ] - > [
+ {
+ mount_point = null
+ size = null
} ,
]
id = "i-02ae66f368e8518a9"
+ root_block_device { }
}
@ -2309,10 +2316,20 @@ func TestResourceChange_nestedList(t *testing.T) {
"root_block_device" : cty . ListValEmpty ( cty . Object ( map [ string ] cty . Type {
"volume_type" : cty . String ,
} ) ) ,
"disks" : cty . ListValEmpty ( cty . Object ( map [ string ] cty . Type {
"mount_point" : cty . String ,
"size" : cty . String ,
} ) ) ,
} ) ,
After : cty . ObjectVal ( map [ string ] cty . Value {
"id" : cty . StringVal ( "i-02ae66f368e8518a9" ) ,
"ami" : cty . StringVal ( "ami-AFTER" ) ,
"disks" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"mount_point" : cty . StringVal ( "/var/diska" ) ,
"size" : cty . NullVal ( cty . String ) ,
} ) ,
} ) ,
"root_block_device" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"volume_type" : cty . StringVal ( "gp2" ) ,
@ -2321,30 +2338,17 @@ func TestResourceChange_nestedList(t *testing.T) {
} ) ,
RequiredReplace : cty . NewPathSet ( ) ,
Tainted : false ,
Schema : & configschema . Block {
Attributes : map [ string ] * configschema . Attribute {
"id" : { Type : cty . String , Optional : true , Computed : true } ,
"ami" : { Type : cty . String , Optional : true } ,
} ,
BlockTypes : map [ string ] * configschema . NestedBlock {
"root_block_device" : {
Block : configschema . Block {
Attributes : map [ string ] * configschema . Attribute {
"volume_type" : {
Type : cty . String ,
Optional : true ,
Computed : true ,
} ,
} ,
} ,
Nesting : configschema . NestingList ,
} ,
} ,
} ,
Schema : testSchemaNestingList ,
ExpectedOutput : ` # test_instance . example will be updated in - place
~ resource "test_instance" "example" {
~ ami = "ami-BEFORE" - > "ami-AFTER"
id = "i-02ae66f368e8518a9"
~ ami = "ami-BEFORE" - > "ami-AFTER"
~ disks = [ ] - > [
+ {
+ mount_point = "/var/diska"
+ size = null
} ,
]
id = "i-02ae66f368e8518a9"
+ root_block_device {
+ volume_type = "gp2"
@ -2358,6 +2362,12 @@ func TestResourceChange_nestedList(t *testing.T) {
Before : cty . ObjectVal ( map [ string ] cty . Value {
"id" : cty . StringVal ( "i-02ae66f368e8518a9" ) ,
"ami" : cty . StringVal ( "ami-BEFORE" ) ,
"disks" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"mount_point" : cty . StringVal ( "/var/diska" ) ,
"size" : cty . NullVal ( cty . String ) ,
} ) ,
} ) ,
"root_block_device" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"volume_type" : cty . StringVal ( "gp2" ) ,
@ -2368,6 +2378,12 @@ func TestResourceChange_nestedList(t *testing.T) {
After : cty . ObjectVal ( map [ string ] cty . Value {
"id" : cty . StringVal ( "i-02ae66f368e8518a9" ) ,
"ami" : cty . StringVal ( "ami-AFTER" ) ,
"disks" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"mount_point" : cty . StringVal ( "/var/diska" ) ,
"size" : cty . StringVal ( "50GB" ) ,
} ) ,
} ) ,
"root_block_device" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"volume_type" : cty . StringVal ( "gp2" ) ,
@ -2381,6 +2397,15 @@ func TestResourceChange_nestedList(t *testing.T) {
Attributes : map [ string ] * configschema . Attribute {
"id" : { Type : cty . String , Optional : true , Computed : true } ,
"ami" : { Type : cty . String , Optional : true } ,
"disks" : {
NestedType : & configschema . Object {
Attributes : map [ string ] * configschema . Attribute {
"mount_point" : { Type : cty . String , Optional : true } ,
"size" : { Type : cty . String , Optional : true } ,
} ,
Nesting : configschema . NestingList ,
} ,
} ,
} ,
BlockTypes : map [ string ] * configschema . NestedBlock {
"root_block_device" : {
@ -2404,8 +2429,14 @@ func TestResourceChange_nestedList(t *testing.T) {
} ,
ExpectedOutput : ` # test_instance . example will be updated in - place
~ resource "test_instance" "example" {
~ ami = "ami-BEFORE" - > "ami-AFTER"
id = "i-02ae66f368e8518a9"
~ ami = "ami-BEFORE" - > "ami-AFTER"
~ disks = [
~ {
~ size = null - > "50GB"
# ( 1 unchanged element hidden )
} ,
]
id = "i-02ae66f368e8518a9"
~ root_block_device {
+ new_field = "new_value"
@ -2414,12 +2445,18 @@ func TestResourceChange_nestedList(t *testing.T) {
}
` ,
} ,
"force-new update (inside block )": {
"force-new update (inside block s )": {
Action : plans . DeleteThenCreate ,
Mode : addrs . ManagedResourceMode ,
Before : cty . ObjectVal ( map [ string ] cty . Value {
"id" : cty . StringVal ( "i-02ae66f368e8518a9" ) ,
"ami" : cty . StringVal ( "ami-BEFORE" ) ,
"disks" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"mount_point" : cty . StringVal ( "/var/diska" ) ,
"size" : cty . StringVal ( "50GB" ) ,
} ) ,
} ) ,
"root_block_device" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"volume_type" : cty . StringVal ( "gp2" ) ,
@ -2429,42 +2466,47 @@ func TestResourceChange_nestedList(t *testing.T) {
After : cty . ObjectVal ( map [ string ] cty . Value {
"id" : cty . StringVal ( "i-02ae66f368e8518a9" ) ,
"ami" : cty . StringVal ( "ami-AFTER" ) ,
"disks" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"mount_point" : cty . StringVal ( "/var/diskb" ) ,
"size" : cty . StringVal ( "50GB" ) ,
} ) ,
} ) ,
"root_block_device" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"volume_type" : cty . StringVal ( "different" ) ,
} ) ,
} ) ,
} ) ,
RequiredReplace : cty . NewPathSet ( cty . Path {
cty . GetAttrStep { Name : "root_block_device" } ,
cty . IndexStep { Key : cty . NumberIntVal ( 0 ) } ,
cty . GetAttrStep { Name : "volume_type" } ,
} ) ,
Tainted : false ,
Schema : & configschema . Block {
Attributes : map [ string ] * configschema . Attribute {
"id" : { Type : cty . String , Optional : true , Computed : true } ,
"ami" : { Type : cty . String , Optional : true } ,
} ,
BlockTypes : map [ string ] * configschema . NestedBlock {
"root_block_device" : {
Block : configschema . Block {
Attributes : map [ string ] * configschema . Attribute {
"volume_type" : {
Type : cty . String ,
Optional : true ,
Computed : true ,
} ,
} ,
} ,
Nesting : configschema . NestingList ,
} ,
RequiredReplace : cty . NewPathSet (
cty . Path {
cty . GetAttrStep { Name : "root_block_device" } ,
cty . IndexStep { Key : cty . NumberIntVal ( 0 ) } ,
cty . GetAttrStep { Name : "volume_type" } ,
} ,
// FIXME: This is not currently used; when the diff printer is
// updated to fully handle NestedTypes this test should fail,
// and the expected output should look like this:
//
// ~ mount_point = "/var/diska" -> "/var/diskb" # forces replacement
cty . Path {
cty . GetAttrStep { Name : "disks" } ,
cty . IndexStep { Key : cty . NumberIntVal ( 0 ) } ,
cty . GetAttrStep { Name : "mount_point" } ,
} ,
} ,
) ,
Tainted : false ,
Schema : testSchemaNestingList ,
ExpectedOutput : ` # test_instance . example must be replaced
- / + resource "test_instance" "example" {
~ ami = "ami-BEFORE" - > "ami-AFTER"
id = "i-02ae66f368e8518a9"
~ ami = "ami-BEFORE" - > "ami-AFTER"
~ disks = [
~ {
~ mount_point = "/var/diska" - > "/var/diskb"
# ( 1 unchanged element hidden )
} ,
]
id = "i-02ae66f368e8518a9"
~ root_block_device {
~ volume_type = "gp2" - > "different" # forces replacement
@ -2478,6 +2520,12 @@ func TestResourceChange_nestedList(t *testing.T) {
Before : cty . ObjectVal ( map [ string ] cty . Value {
"id" : cty . StringVal ( "i-02ae66f368e8518a9" ) ,
"ami" : cty . StringVal ( "ami-BEFORE" ) ,
"disks" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"mount_point" : cty . StringVal ( "/var/diska" ) ,
"size" : cty . StringVal ( "50GB" ) ,
} ) ,
} ) ,
"root_block_device" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"volume_type" : cty . StringVal ( "gp2" ) ,
@ -2487,40 +2535,34 @@ func TestResourceChange_nestedList(t *testing.T) {
After : cty . ObjectVal ( map [ string ] cty . Value {
"id" : cty . StringVal ( "i-02ae66f368e8518a9" ) ,
"ami" : cty . StringVal ( "ami-AFTER" ) ,
"disks" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"mount_point" : cty . StringVal ( "/var/diskb" ) ,
"size" : cty . StringVal ( "50GB" ) ,
} ) ,
} ) ,
"root_block_device" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"volume_type" : cty . StringVal ( "different" ) ,
} ) ,
} ) ,
} ) ,
RequiredReplace : cty . NewPathSet ( cty . Path {
cty . GetAttrStep { Name : "root_block_device" } ,
} ) ,
RequiredReplace : cty . NewPathSet (
cty . Path { cty . GetAttrStep { Name : "root_block_device" } } ,
cty . Path { cty . GetAttrStep { Name : "disks" } } ,
) ,
Tainted : false ,
Schema : & configschema . Block {
Attributes : map [ string ] * configschema . Attribute {
"id" : { Type : cty . String , Optional : true , Computed : true } ,
"ami" : { Type : cty . String , Optional : true } ,
} ,
BlockTypes : map [ string ] * configschema . NestedBlock {
"root_block_device" : {
Block : configschema . Block {
Attributes : map [ string ] * configschema . Attribute {
"volume_type" : {
Type : cty . String ,
Optional : true ,
Computed : true ,
} ,
} ,
} ,
Nesting : configschema . NestingList ,
} ,
} ,
} ,
Schema : testSchemaNestingList ,
ExpectedOutput : ` # test_instance . example must be replaced
- / + resource "test_instance" "example" {
~ ami = "ami-BEFORE" - > "ami-AFTER"
id = "i-02ae66f368e8518a9"
~ ami = "ami-BEFORE" - > "ami-AFTER"
~ disks = [ # forces replacement
~ {
~ mount_point = "/var/diska" - > "/var/diskb"
# ( 1 unchanged element hidden )
} # forces replacement ,
]
id = "i-02ae66f368e8518a9"
~ root_block_device { # forces replacement
~ volume_type = "gp2" - > "different"
@ -2534,55 +2576,44 @@ func TestResourceChange_nestedList(t *testing.T) {
Before : cty . ObjectVal ( map [ string ] cty . Value {
"id" : cty . StringVal ( "i-02ae66f368e8518a9" ) ,
"ami" : cty . StringVal ( "ami-BEFORE" ) ,
"disks" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"mount_point" : cty . StringVal ( "/var/diska" ) ,
"size" : cty . StringVal ( "50GB" ) ,
} ) ,
} ) ,
"root_block_device" : cty . ListVal ( [ ] cty . Value {
cty . ObjectVal ( map [ string ] cty . Value {
"volume_type" : cty . StringVal ( "gp2" ) ,
"new_field" : cty . StringVal ( "new_value" ) ,
} ) ,
} ) ,
} ) ,
After : cty . ObjectVal ( map [ string ] cty . Value {
"id" : cty . StringVal ( "i-02ae66f368e8518a9" ) ,
"ami" : cty . StringVal ( "ami-AFTER" ) ,
"disks" : cty . ListValEmpty ( cty . Object ( map [ string ] cty . Type {
"mount_point" : cty . String ,
"size" : cty . String ,
} ) ) ,
"root_block_device" : cty . ListValEmpty ( cty . Object ( map [ string ] cty . Type {
"volume_type" : cty . String ,
"new_field" : cty . String ,
} ) ) ,
} ) ,
RequiredReplace : cty . NewPathSet ( ) ,
Tainted : false ,
Schema : & configschema . Block {
Attributes : map [ string ] * configschema . Attribute {
"id" : { Type : cty . String , Optional : true , Computed : true } ,
"ami" : { Type : cty . String , Optional : true } ,
} ,
BlockTypes : map [ string ] * configschema . NestedBlock {
"root_block_device" : {
Block : configschema . Block {
Attributes : map [ string ] * configschema . Attribute {
"volume_type" : {
Type : cty . String ,
Optional : true ,
Computed : true ,
} ,
"new_field" : {
Type : cty . String ,
Optional : true ,
Computed : true ,
} ,
} ,
} ,
Nesting : configschema . NestingList ,
} ,
} ,
} ,
Schema : testSchemaNestingList ,
ExpectedOutput : ` # test_instance . example will be updated in - place
~ resource "test_instance" "example" {
~ ami = "ami-BEFORE" - > "ami-AFTER"
id = "i-02ae66f368e8518a9"
~ ami = "ami-BEFORE" - > "ami-AFTER"
~ disks = [
- {
- mount_point = "/var/diska"
- size = "50GB"
} ,
] - > [ ]
id = "i-02ae66f368e8518a9"
- root_block_device {
- new_field = "new_value" - > null
- volume_type = "gp2" - > null
}
}
@ -4311,3 +4342,34 @@ func outputChange(name string, before, after cty.Value, sensitive bool) *plans.O
return changeSrc
}
// A basic test schema using NestingList for one attribute and one block
var testSchemaNestingList = & configschema . Block {
Attributes : map [ string ] * configschema . Attribute {
"id" : { Type : cty . String , Optional : true , Computed : true } ,
"ami" : { Type : cty . String , Optional : true } ,
"disks" : {
NestedType : & configschema . Object {
Attributes : map [ string ] * configschema . Attribute {
"mount_point" : { Type : cty . String , Optional : true } ,
"size" : { Type : cty . String , Optional : true } ,
} ,
Nesting : configschema . NestingList ,
} ,
} ,
} ,
BlockTypes : map [ string ] * configschema . NestedBlock {
"root_block_device" : {
Block : configschema . Block {
Attributes : map [ string ] * configschema . Attribute {
"volume_type" : {
Type : cty . String ,
Optional : true ,
Computed : true ,
} ,
} ,
} ,
Nesting : configschema . NestingList ,
} ,
} ,
}