Skip to content
This repository was archived by the owner on Mar 1, 2023. It is now read-only.

Commit e225f6c

Browse files
committed
start/stop instance added
some fix in volume's resource
1 parent e0c0f9c commit e225f6c

File tree

3 files changed

+81
-13
lines changed

3 files changed

+81
-13
lines changed

docs/resources/gcore_instance.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ resource "gcore_instance" "instance" {
139139
- **status** (String)
140140
- **userdata** (String)
141141
- **username** (String)
142-
- **vm_state** (String)
142+
- **vm_state** (String) Current vm state, use stopped to stop vm and active to start
143143

144144
<a id="nestedblock--interface"></a>
145145
### Nested Schema for `interface`

gcore/resource_gcore_instance.go

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,19 @@ import (
1414
"github.com/G-Core/gcorelabscloud-go/gcore/volume/v1/volumes"
1515
"github.com/hashicorp/go-cty/cty"
1616
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
17+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
1718
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
19+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
1820
)
1921

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+
)
2330

2431
func resourceInstance() *schema.Resource {
2532
return &schema.Resource{
@@ -128,6 +135,7 @@ func resourceInstance() *schema.Resource {
128135
"size": {
129136
Type: schema.TypeInt,
130137
Optional: true,
138+
Computed: true,
131139
},
132140
"volume_id": {
133141
Type: schema.TypeString,
@@ -280,9 +288,13 @@ func resourceInstance() *schema.Resource {
280288
Computed: true,
281289
},
282290
"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),
286298
},
287299
"addresses": &schema.Schema{
288300
Type: schema.TypeList,
@@ -773,6 +785,42 @@ func resourceInstanceUpdate(ctx context.Context, d *schema.ResourceData, m inter
773785
}
774786
}
775787

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+
776824
d.Set("last_updated", time.Now().Format(time.RFC850))
777825
log.Println("[DEBUG] Finish Instance updating")
778826
return resourceInstanceRead(ctx, d, m)
@@ -820,3 +868,19 @@ func resourceInstanceDelete(ctx context.Context, d *schema.ResourceData, m inter
820868
log.Printf("[DEBUG] Finish of Instance deleting")
821869
return diags
822870
}
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+
}

gcore/resource_gcore_volume.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,13 @@ func resourceVolume() *schema.Resource {
9090
"image_id": &schema.Schema{
9191
Type: schema.TypeString,
9292
Optional: true,
93+
ForceNew: true,
9394
Description: "Mandatory if volume is created from image",
9495
},
9596
"snapshot_id": &schema.Schema{
9697
Type: schema.TypeString,
9798
Optional: true,
99+
ForceNew: true,
98100
Description: "Mandatory if volume is created from a snapshot",
99101
},
100102
"last_updated": &schema.Schema{
@@ -203,13 +205,15 @@ func resourceVolumeUpdate(ctx context.Context, d *schema.ResourceData, m interfa
203205
if d.HasChange("size") {
204206
newValue := d.Get("size")
205207
newSize := newValue.(int)
206-
if volume.Size < newSize {
207-
err = ExtendVolume(client, volumeID, newSize)
208-
if err != nil {
209-
return diag.FromErr(err)
208+
if newSize != 0 {
209+
if volume.Size < newSize {
210+
err = ExtendVolume(client, volumeID, newSize)
211+
if err != nil {
212+
return diag.FromErr(err)
213+
}
214+
} else {
215+
return diag.Errorf("Validation error: unable to update size field because new volume size must be greater than current size")
210216
}
211-
} else {
212-
return diag.Errorf("Validation error: unable to update size field because new volume size must be greater than current size")
213217
}
214218
}
215219

0 commit comments

Comments
 (0)