@@ -14,12 +14,19 @@ import (
14
14
"github.com/G-Core/gcorelabscloud-go/gcore/volume/v1/volumes"
15
15
"github.com/hashicorp/go-cty/cty"
16
16
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
17
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
17
18
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
19
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
18
20
)
19
21
20
- const InstanceDeleting int = 1200
21
- const InstanceCreatingTimeout int = 1200
22
- const InstancePoint = "instances"
22
+ const (
23
+ InstanceDeleting int = 1200
24
+ InstanceCreatingTimeout int = 1200
25
+ InstancePoint = "instances"
26
+
27
+ InstanceVMStateActive = "active"
28
+ InstanceVMStateStopped = "stopped"
29
+ )
23
30
24
31
func resourceInstance () * schema.Resource {
25
32
return & schema.Resource {
@@ -128,6 +135,7 @@ func resourceInstance() *schema.Resource {
128
135
"size" : {
129
136
Type : schema .TypeInt ,
130
137
Optional : true ,
138
+ Computed : true ,
131
139
},
132
140
"volume_id" : {
133
141
Type : schema .TypeString ,
@@ -280,9 +288,13 @@ func resourceInstance() *schema.Resource {
280
288
Computed : true ,
281
289
},
282
290
"vm_state" : & schema.Schema {
283
- Type : schema .TypeString ,
284
- Optional : true ,
285
- Computed : true ,
291
+ Type : schema .TypeString ,
292
+ Optional : true ,
293
+ Computed : true ,
294
+ Description : fmt .Sprintf ("Current vm state, use %s to stop vm and %s to start" , InstanceVMStateStopped , InstanceVMStateActive ),
295
+ ValidateFunc : validation .StringInSlice ([]string {
296
+ InstanceVMStateActive , InstanceVMStateStopped ,
297
+ }, true ),
286
298
},
287
299
"addresses" : & schema.Schema {
288
300
Type : schema .TypeList ,
@@ -773,6 +785,42 @@ func resourceInstanceUpdate(ctx context.Context, d *schema.ResourceData, m inter
773
785
}
774
786
}
775
787
788
+ if d .HasChange ("vm_state" ) {
789
+ state := d .Get ("vm_state" ).(string )
790
+ switch state {
791
+ case InstanceVMStateActive :
792
+ if _ , err := instances .Start (client , instanceID ).Extract (); err != nil {
793
+ return diag .FromErr (err )
794
+ }
795
+ startStateConf := & resource.StateChangeConf {
796
+ Target : []string {InstanceVMStateActive },
797
+ Refresh : ServerV2StateRefreshFunc (client , instanceID ),
798
+ Timeout : d .Timeout (schema .TimeoutCreate ),
799
+ Delay : 10 * time .Second ,
800
+ MinTimeout : 3 * time .Second ,
801
+ }
802
+ _ , err = startStateConf .WaitForStateContext (ctx )
803
+ if err != nil {
804
+ return diag .Errorf ("Error waiting for instance (%s) to become active: %s" , d .Id (), err )
805
+ }
806
+ case InstanceVMStateStopped :
807
+ if _ , err := instances .Stop (client , instanceID ).Extract (); err != nil {
808
+ return diag .FromErr (err )
809
+ }
810
+ stopStateConf := & resource.StateChangeConf {
811
+ Target : []string {InstanceVMStateStopped },
812
+ Refresh : ServerV2StateRefreshFunc (client , instanceID ),
813
+ Timeout : d .Timeout (schema .TimeoutCreate ),
814
+ Delay : 10 * time .Second ,
815
+ MinTimeout : 3 * time .Second ,
816
+ }
817
+ _ , err = stopStateConf .WaitForStateContext (ctx )
818
+ if err != nil {
819
+ return diag .Errorf ("Error waiting for instance (%s) to become inactive(stopped): %s" , d .Id (), err )
820
+ }
821
+ }
822
+ }
823
+
776
824
d .Set ("last_updated" , time .Now ().Format (time .RFC850 ))
777
825
log .Println ("[DEBUG] Finish Instance updating" )
778
826
return resourceInstanceRead (ctx , d , m )
@@ -820,3 +868,19 @@ func resourceInstanceDelete(ctx context.Context, d *schema.ResourceData, m inter
820
868
log .Printf ("[DEBUG] Finish of Instance deleting" )
821
869
return diags
822
870
}
871
+
872
+ // ServerV2StateRefreshFunc returns a resource.StateRefreshFunc that is used to watch
873
+ // a gcorecloud instance.
874
+ func ServerV2StateRefreshFunc (client * gcorecloud.ServiceClient , instanceID string ) resource.StateRefreshFunc {
875
+ return func () (interface {}, string , error ) {
876
+ s , err := instances .Get (client , instanceID ).Extract ()
877
+ if err != nil {
878
+ if _ , ok := err .(gcorecloud.ErrDefault404 ); ok {
879
+ return s , "DELETED" , nil
880
+ }
881
+ return nil , "" , err
882
+ }
883
+
884
+ return s , s .VMState , nil
885
+ }
886
+ }
0 commit comments