55 "encoding/json"
66 "fmt"
77 "log"
8+ "strconv"
89 "time"
910
1011 "github.com/gomorpheus/morpheus-go-sdk"
@@ -360,11 +361,16 @@ func resourceMVMInstanceCreate(ctx context.Context, d *schema.ResourceData, meta
360361 var itemResponsePayload ResourcePoolOptions
361362 json .Unmarshal (resourcePoolResp .Body , & itemResponsePayload )
362363 var resourcePoolId int
364+ resourcePoolFound := false
363365 for _ , v := range itemResponsePayload .Data {
364366 if v .ProviderType == "mvm" && v .Name == d .Get ("resource_pool_name" ).(string ) {
365367 resourcePoolId = v .Id
368+ resourcePoolFound = true
366369 }
367370 }
371+ if ! resourcePoolFound {
372+ return diag .Errorf ("resource pool with name %s not found with providerType mvm" , d .Get ("resource_pool_name" ).(string ))
373+ }
368374
369375 config ["resourcePoolId" ] = resourcePoolId
370376 config ["poolProviderType" ] = "mvm"
@@ -590,16 +596,33 @@ func resourceMVMInstanceRead(ctx context.Context, d *schema.ResourceData, meta i
590596 d .Set ("labels" , instance .Labels )
591597
592598 var evars []map [string ]interface {}
599+ evarMap := make (map [string ]string , len (instance .EnvironmentVariables ))
593600 for i := 0 ; i < len (instance .EnvironmentVariables ); i ++ {
594601 evar := instance .EnvironmentVariables [i ]
595602 row := make (map [string ]interface {})
596603 row ["name" ] = evar .Name
597- row ["value" ] = fmt .Sprintf ("%v" , evar .Value )
604+ value := fmt .Sprintf ("%v" , evar .Value )
605+ row ["value" ] = value
598606 row ["export" ] = evar .Export
599607 row ["masked" ] = evar .Masked
608+ evarMap [evar .Name ] = value
600609 evars = append (evars , row )
601610 }
602- d .Set ("evar" , evars )
611+
612+ // If the evar field is set, we need to check if the evars match
613+ if d .Get ("evar" ) != nil {
614+ for _ , row := range d .Get ("evar" ).([]interface {}) {
615+ evarData := row .(map [string ]interface {})
616+ evarName := evarData ["name" ].(string )
617+ value := evarData ["value" ].(string )
618+
619+ if mapValue , exists := evarMap [evarName ]; exists {
620+ if mapValue != value {
621+ return diag .Errorf ("evar %s is missing from returned evar map" , evarName )
622+ }
623+ }
624+ }
625+ }
603626
604627 // Tags
605628 tags := make (map [string ]interface {})
@@ -632,19 +655,59 @@ func resourceMVMInstanceRead(ctx context.Context, d *schema.ResourceData, meta i
632655 d .Set ("primary_ip_address" , instance .ConnectionInfo [0 ].Ip )
633656
634657 var volumes []map [string ]interface {}
635- // iterate over the array of svcports
658+ // iterate over the array of volumes
636659 for i := 0 ; i < len (instance .Volumes ); i ++ {
637660 row := make (map [string ]interface {})
638661 volume := instance .Volumes [i ]
639662 row ["uuid" ] = volume .Uuid
640663 row ["root" ] = volume .RootVolume .(bool )
641664 row ["name" ] = volume .Name
642- row ["size" ] = volume .Size .(float64 )
643- row ["storage_type" ] = volume .StorageType .(float64 )
644- row ["datastore_id" ] = volume .DatastoreId .(int )
665+ if volume .Size != nil {
666+ row ["size" ] = volume .Size .(float64 )
667+ }
668+ if volume .StorageType != nil {
669+ row ["storage_type" ] = volume .StorageType .(float64 )
670+ }
671+ if volume .DatastoreId != nil {
672+ datastoreId , errConv := convertToInt (volume .DatastoreId )
673+ if errConv != nil {
674+ log .Printf ("Error converting datastore ID to int: %s" , errConv )
675+
676+ return diag .FromErr (errConv )
677+ }
678+
679+ row ["datastore_id" ] = datastoreId
680+ }
645681 volumes = append (volumes , row )
646682 }
647- d .Set ("storage_volume" , volumes )
683+
684+ // If the storage_volume field is set, we need to check if the volumes match
685+ // And it there is a match, we need to set the uuid in the state
686+ var volumesForState []map [string ]interface {}
687+ if d .Get ("storage_volume" ) != nil {
688+ for _ , row := range d .Get ("storage_volume" ).([]interface {}) {
689+ volumeData := row .(map [string ]interface {})
690+ volumeName := volumeData ["name" ]
691+ datastoreId := volumeData ["datastore_id" ]
692+
693+ found := false
694+ for _ , v := range volumes {
695+ if v ["name" ] == volumeName && v ["datastore_id" ] == datastoreId {
696+ found = true
697+ volumeData ["uuid" ] = v ["uuid" ]
698+ volumesForState = append (volumesForState , volumeData )
699+
700+ break
701+ }
702+ }
703+ if ! found {
704+ return diag .Errorf ("storage_volume %s is missing from returned storage volume map" , volumeName )
705+ }
706+ }
707+ }
708+ if len (volumesForState ) > 0 {
709+ d .Set ("storage_volume" , volumesForState )
710+ }
648711
649712 var networkInterfaces []map [string ]interface {}
650713 // iterate over the array of svcports
@@ -662,6 +725,18 @@ func resourceMVMInstanceRead(ctx context.Context, d *schema.ResourceData, meta i
662725 return diags
663726}
664727
728+ // convertToInt converts a value to an int, supporting both int and string types.
729+ func convertToInt (value interface {}) (int , error ) {
730+ switch v := value .(type ) {
731+ case int :
732+ return v , nil
733+ case string :
734+ return strconv .Atoi (v )
735+ default :
736+ return 0 , fmt .Errorf ("unsupported type %T for conversion to int" , value )
737+ }
738+ }
739+
665740func resourceMVMInstanceUpdate (ctx context.Context , d * schema.ResourceData , meta interface {}) diag.Diagnostics {
666741 client := meta .(* morpheus.Client )
667742 id := d .Id ()
0 commit comments