77 "encoding/hex"
88 "fmt"
99 "log"
10+ "reflect"
1011 "sort"
1112 "strconv"
1213 "strings"
@@ -309,6 +310,13 @@ func ResourceTencentCloudInstance() *schema.Resource {
309310 ForceNew : true ,
310311 Description : "Decides whether the disk is deleted with instance(only applied to `CLOUD_BASIC`, `CLOUD_SSD` and `CLOUD_PREMIUM` disk with `PREPAID` instance), default is false." ,
311312 },
313+ "kms_key_id" : {
314+ Type : schema .TypeString ,
315+ Optional : true ,
316+ ForceNew : true ,
317+ Computed : true ,
318+ Description : "Optional parameters. When purchasing an encryption disk, customize the key. When this parameter is passed in, the `encrypt` parameter need be set." ,
319+ },
312320 "encrypt" : {
313321 Type : schema .TypeBool ,
314322 Optional : true ,
@@ -678,6 +686,10 @@ func resourceTencentCloudInstanceCreate(d *schema.ResourceData, meta interface{}
678686 dataDisk .DeleteWithInstance = & deleteWithInstanceBool
679687 }
680688
689+ if v , ok := value ["kms_key_id" ]; ok && v != "" {
690+ dataDisk .KmsKeyId = helper .String (v .(string ))
691+ }
692+
681693 if encrypt , ok := value ["encrypt" ]; ok {
682694 encryptBool := encrypt .(bool )
683695 dataDisk .Encrypt = & encryptBool
@@ -1024,7 +1036,7 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{})
10241036 }
10251037
10261038 // set data_disks
1027- var hasDataDisks , isCombineDataDisks , hasDataDisksId , hasDataDisksName bool
1039+ var hasDataDisks , isCombineDataDisks , hasDataDisksId bool
10281040 dataDiskList := make ([]map [string ]interface {}, 0 , len (instance .DataDisks ))
10291041 diskSizeMap := map [string ]* uint64 {}
10301042 diskOrderMap := make (map [string ]int )
@@ -1044,13 +1056,6 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{})
10441056 hasDataDisksId = true
10451057 }
10461058 }
1047-
1048- if v , ok := value ["data_disk_name" ]; ok && v != nil {
1049- diskName := v .(string )
1050- if diskName != "" {
1051- hasDataDisksName = true
1052- }
1053- }
10541059 }
10551060 }
10561061
@@ -1070,6 +1075,14 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{})
10701075 if value ["data_disk_id" ].(string ) == * item .DiskId {
10711076 value ["data_disk_name" ] = * item .DiskName
10721077 value ["data_disk_size" ] = int (* item .DiskSize )
1078+ value ["data_disk_type" ] = * item .DiskType
1079+ if item .KmsKeyId != nil {
1080+ value ["kms_key_id" ] = * item .KmsKeyId
1081+ }
1082+
1083+ value ["encrypt" ] = * item .Encrypt
1084+ value ["throughput_performance" ] = * item .ThroughputPerformance
1085+ value ["delete_with_instance" ] = * item .DeleteWithInstance
10731086 break
10741087 }
10751088 }
@@ -1087,7 +1100,7 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{})
10871100 }
10881101
10891102 // scene with has disks name
1090- if len (instance .DataDisks ) > 0 && ! hasDataDisksName {
1103+ if len (instance .DataDisks ) > 0 && ! hasDataDisksId {
10911104 var diskIds []* string
10921105 for i := range instance .DataDisks {
10931106 id := instance .DataDisks [i ].DiskId
@@ -1143,7 +1156,7 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{})
11431156 }
11441157
11451158 for _ , disk := range instance .DataDisks {
1146- dataDisk := make (map [string ]interface {}, 5 )
1159+ dataDisk := make (map [string ]interface {})
11471160 if ! strings .HasPrefix (* disk .DiskId , "disk-" ) {
11481161 continue
11491162 }
@@ -1158,6 +1171,7 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{})
11581171 dataDisk ["data_disk_type" ] = disk .DiskType
11591172 dataDisk ["data_disk_snapshot_id" ] = disk .SnapshotId
11601173 dataDisk ["delete_with_instance" ] = disk .DeleteWithInstance
1174+ dataDisk ["kms_key_id" ] = disk .KmsKeyId
11611175 dataDisk ["encrypt" ] = disk .Encrypt
11621176 dataDisk ["throughput_performance" ] = disk .ThroughputPerformance
11631177 dataDiskList = append (dataDiskList , dataDisk )
@@ -1171,17 +1185,6 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{})
11711185 })
11721186 }
11731187
1174- // set data disk delete_with_instance_prepaid
1175- for i := range dataDiskList {
1176- dataDiskList [i ]["delete_with_instance_prepaid" ] = false
1177- if hasDataDisks {
1178- tmpDataDisk := tmpDataDisks [i ].(map [string ]interface {})
1179- if deleteWithInstancePrepaidBool , ok := tmpDataDisk ["delete_with_instance_prepaid" ].(bool ); ok {
1180- dataDiskList [i ]["delete_with_instance_prepaid" ] = deleteWithInstancePrepaidBool
1181- }
1182- }
1183- }
1184-
11851188 // set data disk name
11861189 finalDiskIds := make ([]* string , 0 , len (dataDiskList ))
11871190 for _ , item := range dataDiskList {
@@ -1215,9 +1218,25 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{})
12151218 }
12161219 }
12171220
1218- _ = d .Set ("data_disks" , dataDiskList )
1221+ sortedDataDiskList , err := sortDataDisks (tmpDataDisks , dataDiskList )
1222+ if err != nil {
1223+ return err
1224+ }
1225+
1226+ // set data disk delete_with_instance_prepaid
1227+ for i := range sortedDataDiskList {
1228+ sortedDataDiskList [i ]["delete_with_instance_prepaid" ] = false
1229+ if hasDataDisks {
1230+ tmpDataDisk := tmpDataDisks [i ].(map [string ]interface {})
1231+ if deleteWithInstancePrepaidBool , ok := tmpDataDisk ["delete_with_instance_prepaid" ].(bool ); ok {
1232+ sortedDataDiskList [i ]["delete_with_instance_prepaid" ] = deleteWithInstancePrepaidBool
1233+ }
1234+ }
1235+ }
1236+
1237+ _ = d .Set ("data_disks" , sortedDataDiskList )
12191238 }
1220- } else if len (instance .DataDisks ) > 0 && hasDataDisksName {
1239+ } else if len (instance .DataDisks ) > 0 && hasDataDisksId {
12211240 // scene with no disks name
12221241 dDiskHash := make ([]map [string ]interface {}, 0 )
12231242 // get source disk hash
@@ -1234,6 +1253,7 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{})
12341253 diskType := value ["data_disk_type" ].(string )
12351254 diskSize := int64 (value ["data_disk_size" ].(int ))
12361255 deleteWithInstance := value ["delete_with_instance" ].(bool )
1256+ kmsKeyId := value ["kms_key_id" ].(string )
12371257 encrypt := value ["encrypt" ].(bool )
12381258 if tmpV , ok := value ["data_disk_name" ].(string ); ok && tmpV != "" {
12391259 diskName = tmpV
@@ -1243,6 +1263,7 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{})
12431263 diskType : diskType ,
12441264 diskSize : diskSize ,
12451265 deleteWithInstance : deleteWithInstance ,
1266+ kmsKeyId : kmsKeyId ,
12461267 encrypt : encrypt ,
12471268 }
12481269
@@ -1301,6 +1322,7 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{})
13011322 dataDisk ["data_disk_type" ] = cvmDisk .DiskType
13021323 dataDisk ["data_disk_snapshot_id" ] = cvmDisk .SnapshotId
13031324 dataDisk ["delete_with_instance" ] = cvmDisk .DeleteWithInstance
1325+ dataDisk ["kms_key_id" ] = cvmDisk .KmsKeyId
13041326 dataDisk ["encrypt" ] = cvmDisk .Encrypt
13051327 dataDisk ["throughput_performance" ] = cvmDisk .ThroughputPerformance
13061328 dataDisk ["flag" ] = 0
@@ -1313,17 +1335,24 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{})
13131335 // has set disk name first
13141336 for v := range sourceDataDisks {
13151337 for i := range dDiskHash {
1338+ var kmsKeyId * string
13161339 disk := * sourceDataDisks [v ]
13171340 diskFlag := disk ["flag" ].(int )
13181341 diskName := disk ["data_disk_name" ].(* string )
13191342 diskType := disk ["data_disk_type" ].(* string )
13201343 diskSize := disk ["data_disk_size" ].(* int64 )
13211344 deleteWithInstance := disk ["delete_with_instance" ].(* bool )
1345+ if v , ok := disk ["kms_key_id" ].(* string ); ok && v != nil {
1346+ kmsKeyId = v
1347+ } else {
1348+ kmsKeyId = helper .String ("" )
1349+ }
13221350 encrypt := disk ["encrypt" ].(* bool )
13231351 tmpHash := getDataDiskHash (diskHash {
13241352 diskType : * diskType ,
13251353 diskSize : * diskSize ,
13261354 deleteWithInstance : * deleteWithInstance ,
1355+ kmsKeyId : * kmsKeyId ,
13271356 encrypt : * encrypt ,
13281357 })
13291358
@@ -1339,6 +1368,7 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{})
13391368 dataDisk ["data_disk_type" ] = disk ["data_disk_type" ]
13401369 dataDisk ["data_disk_snapshot_id" ] = disk ["data_disk_snapshot_id" ]
13411370 dataDisk ["delete_with_instance" ] = disk ["delete_with_instance" ]
1371+ dataDisk ["kms_key_id" ] = disk ["kms_key_id" ]
13421372 dataDisk ["encrypt" ] = disk ["encrypt" ]
13431373 dataDisk ["throughput_performance" ] = disk ["throughput_performance" ]
13441374 tmpDataDiskMap [hashItem ["index" ].(int )] = dataDisk
@@ -1353,16 +1383,23 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{})
13531383 // no set disk name last
13541384 for v := range sourceDataDisks {
13551385 for i := range dDiskHash {
1386+ var kmsKeyId * string
13561387 disk := * sourceDataDisks [v ]
13571388 diskFlag := disk ["flag" ].(int )
13581389 diskType := disk ["data_disk_type" ].(* string )
13591390 diskSize := disk ["data_disk_size" ].(* int64 )
13601391 deleteWithInstance := disk ["delete_with_instance" ].(* bool )
1392+ if v , ok := disk ["kms_key_id" ].(* string ); ok && v != nil {
1393+ kmsKeyId = v
1394+ } else {
1395+ kmsKeyId = helper .String ("" )
1396+ }
13611397 encrypt := disk ["encrypt" ].(* bool )
13621398 tmpHash := getDataDiskHash (diskHash {
13631399 diskType : * diskType ,
13641400 diskSize : * diskSize ,
13651401 deleteWithInstance : * deleteWithInstance ,
1402+ kmsKeyId : * kmsKeyId ,
13661403 encrypt : * encrypt ,
13671404 })
13681405
@@ -1376,6 +1413,7 @@ func resourceTencentCloudInstanceRead(d *schema.ResourceData, meta interface{})
13761413 dataDisk ["data_disk_type" ] = disk ["data_disk_type" ]
13771414 dataDisk ["data_disk_snapshot_id" ] = disk ["data_disk_snapshot_id" ]
13781415 dataDisk ["delete_with_instance" ] = disk ["delete_with_instance" ]
1416+ dataDisk ["kms_key_id" ] = disk ["kms_key_id" ]
13791417 dataDisk ["encrypt" ] = disk ["encrypt" ]
13801418 dataDisk ["throughput_performance" ] = disk ["throughput_performance" ]
13811419 tmpDataDiskMap [hashItem ["index" ].(int )] = dataDisk
@@ -2533,6 +2571,7 @@ type diskHash struct {
25332571 diskType string
25342572 diskSize int64
25352573 deleteWithInstance bool
2574+ kmsKeyId string
25362575 encrypt bool
25372576}
25382577
@@ -2541,6 +2580,121 @@ func getDataDiskHash(obj diskHash) string {
25412580 h .Write ([]byte (obj .diskType ))
25422581 h .Write ([]byte (fmt .Sprintf ("%d" , obj .diskSize )))
25432582 h .Write ([]byte (fmt .Sprintf ("%t" , obj .deleteWithInstance )))
2583+ h .Write ([]byte (obj .kmsKeyId ))
25442584 h .Write ([]byte (fmt .Sprintf ("%t" , obj .encrypt )))
25452585 return hex .EncodeToString (h .Sum (nil ))
25462586}
2587+
2588+ func sortDataDisks (tmpDataDisks []interface {}, dataDiskList []map [string ]interface {}) (sortedList []map [string ]interface {}, err error ) {
2589+ // import
2590+ if len (tmpDataDisks ) == 0 {
2591+ return dataDiskList , nil
2592+ }
2593+
2594+ if len (tmpDataDisks ) != len (dataDiskList ) {
2595+ err = fmt .Errorf ("Inconsistent number of data disks." )
2596+ return
2597+ }
2598+
2599+ remainingDisks := make ([]map [string ]interface {}, len (dataDiskList ))
2600+ copy (remainingDisks , dataDiskList )
2601+
2602+ for _ , tmpDisk := range tmpDataDisks {
2603+ dMap := tmpDisk .(map [string ]interface {})
2604+ tmpName , _ := dMap ["data_disk_name" ].(string )
2605+ tmpSizeRaw := dMap ["data_disk_size" ]
2606+ tmpSize , e := extractInt (tmpSizeRaw )
2607+ if e != nil {
2608+ return nil , e
2609+ }
2610+
2611+ tmpType , _ := dMap ["data_disk_type" ].(string )
2612+ tmpKmsKeyId , _ := dMap ["kms_key_id" ].(string )
2613+ tmpEncrypt , _ := dMap ["encrypt" ].(bool )
2614+ tmpDelWithIns , _ := dMap ["delete_with_instance" ].(bool )
2615+ tmpTpRaw := dMap ["throughput_performance" ]
2616+ tmpTp , e := extractInt (tmpTpRaw )
2617+ if e != nil {
2618+ return nil , e
2619+ }
2620+
2621+ var matchedDisk map [string ]interface {}
2622+ matchedIndex := - 1
2623+
2624+ for i , dataDisk := range remainingDisks {
2625+ dataName , _ := dataDisk ["data_disk_name" ].(* string )
2626+ dataSizeRaw := dataDisk ["data_disk_size" ]
2627+ dataSize , e := extractInt (dataSizeRaw )
2628+ if e != nil {
2629+ return nil , e
2630+ }
2631+
2632+ dataType , _ := dataDisk ["data_disk_type" ].(* string )
2633+ dataKmsKeyId , _ := dataDisk ["kms_key_id" ].(* string )
2634+ dataEncrypt , _ := dataDisk ["encrypt" ].(* bool )
2635+ dataDelWithIns , _ := dataDisk ["delete_with_instance" ].(* bool )
2636+ dataTpRaw := dataDisk ["throughput_performance" ]
2637+ dataTp , e := extractInt (dataTpRaw )
2638+ if e != nil {
2639+ return nil , e
2640+ }
2641+
2642+ match := true
2643+ if tmpName != "" && * dataName != tmpName {
2644+ match = false
2645+ }
2646+
2647+ if tmpKmsKeyId != "" && dataKmsKeyId != nil {
2648+ if tmpKmsKeyId != * dataKmsKeyId {
2649+ match = false
2650+ }
2651+ }
2652+
2653+ if dataSize != tmpSize || * dataType != tmpType || * dataEncrypt != tmpEncrypt || * dataDelWithIns != tmpDelWithIns || dataTp != tmpTp {
2654+ match = false
2655+ }
2656+
2657+ if match {
2658+ matchedDisk = dataDisk
2659+ matchedIndex = i
2660+ break
2661+ }
2662+ }
2663+
2664+ if matchedIndex == - 1 {
2665+ err = fmt .Errorf ("Unable to find match: tmpDisk = %v" , tmpDisk )
2666+ return
2667+ }
2668+
2669+ sortedList = append (sortedList , matchedDisk )
2670+ remainingDisks = append (remainingDisks [:matchedIndex ], remainingDisks [matchedIndex + 1 :]... )
2671+ }
2672+
2673+ return
2674+ }
2675+
2676+ func extractInt (value interface {}) (int , error ) {
2677+ if value == nil {
2678+ return 0 , fmt .Errorf ("value is nil." )
2679+ }
2680+
2681+ if reflect .TypeOf (value ).Kind () == reflect .Ptr {
2682+ ptrValue := reflect .ValueOf (value ).Elem ().Interface ()
2683+ return extractInt (ptrValue )
2684+ }
2685+
2686+ switch v := value .(type ) {
2687+ case int :
2688+ return v , nil
2689+ case float64 :
2690+ return int (v ), nil
2691+ case uint64 :
2692+ return int (v ), nil
2693+ case int32 :
2694+ return int (v ), nil
2695+ case int64 :
2696+ return int (v ), nil
2697+ default :
2698+ return 0 , fmt .Errorf ("Unrecognized numerical type: %T." , value )
2699+ }
2700+ }
0 commit comments