@@ -2,6 +2,7 @@ package cbh
22
33import (
44 "context"
5+ "errors"
56 "fmt"
67 "log"
78 "strings"
@@ -116,12 +117,13 @@ func ResourceCBHInstance() *schema.Resource {
116117 ForceNew : true ,
117118 ValidateFunc : validation .StringInSlice ([]string {
118119 "prePaid" ,
120+ "postPaid" ,
119121 }, false ),
120122 Description : `Specifies the charging mode of the CBH instance.` ,
121123 },
122124 "period_unit" : {
123125 Type : schema .TypeString ,
124- Required : true ,
126+ Optional : true ,
125127 ForceNew : true ,
126128 ValidateFunc : validation .StringInSlice ([]string {
127129 "month" , "year" ,
@@ -130,7 +132,7 @@ func ResourceCBHInstance() *schema.Resource {
130132 },
131133 "period" : {
132134 Type : schema .TypeInt ,
133- Required : true ,
135+ Optional : true ,
134136 ForceNew : true ,
135137 Description : `Specifies the charging period of the CBH instance.` ,
136138 },
@@ -208,45 +210,57 @@ func resourceCBHInstanceCreate(ctx context.Context, d *schema.ResourceData, meta
208210 cfg = meta .(* config.Config )
209211 region = cfg .GetRegion (d )
210212 createCbhInstanceProduct = "cbh"
213+ serverId string
211214 )
212215
213216 client , err := cfg .NewServiceClient (createCbhInstanceProduct , region )
214217 if err != nil {
215218 return diag .Errorf ("error creating CBH client: %s" , err )
216219 }
217220
218- orderId , err := createCBHInstance (client , d , cfg )
219- if err != nil {
220- return diag .FromErr (err )
221- }
222-
223221 bssClient , err := cfg .BssV2Client (cfg .GetRegion (d ))
224222 if err != nil {
225223 return diag .Errorf ("error creating BSS v2 client: %s" , err )
226224 }
227225
228- if err := common .WaitOrderComplete (ctx , bssClient , orderId , d .Timeout (schema .TimeoutCreate )); err != nil {
229- return diag .FromErr (err )
230- }
226+ if d .Get ("charging_mode" ).(string ) == "prePaid" {
227+ orderId , err := createCBHInstance (client , d , cfg )
228+ if err != nil {
229+ return diag .FromErr (err )
230+ }
231231
232- resourceId , err := common .WaitOrderResourceComplete (ctx , bssClient , orderId , d .Timeout (schema .TimeoutCreate ))
233- if err != nil {
234- return diag .Errorf ("error waiting for CBH instance order %s complete: %s" , orderId , err )
235- }
232+ if err := common .WaitOrderComplete (ctx , bssClient , orderId , d .Timeout (schema .TimeoutCreate )); err != nil {
233+ return diag .FromErr (err )
234+ }
236235
237- instances , err := getCBHInstanceList (client )
238- if err != nil {
239- return diag .FromErr (err )
240- }
241- expression := fmt .Sprintf ("[?resource_info.resource_id == '%s']|[0].server_id" , resourceId )
242- serverId := utils .PathSearch (expression , instances , "" ).(string )
243- if serverId == "" {
244- return diag .Errorf ("unable to find the CBH instance ID from the API response" )
245- }
236+ resourceId , err := common .WaitOrderResourceComplete (ctx , bssClient , orderId , d .Timeout (schema .TimeoutCreate ))
237+ if err != nil {
238+ return diag .Errorf ("error waiting for CBH instance order %s complete: %s" , orderId , err )
239+ }
246240
247- d .SetId (serverId )
248- if err := waitingForCBHInstanceActive (ctx , client , d , d .Timeout (schema .TimeoutCreate )); err != nil {
249- return diag .Errorf ("error waiting for CBH instance (%s) creation to active: %s" , d .Id (), err )
241+ instances , err := getCBHInstanceList (client )
242+ if err != nil {
243+ return diag .FromErr (err )
244+ }
245+ expression := fmt .Sprintf ("[?resource_info.resource_id == '%s']|[0].server_id" , resourceId )
246+ serverId = utils .PathSearch (expression , instances , "" ).(string )
247+ if serverId == "" {
248+ return diag .Errorf ("unable to find the CBH instance ID from the API response" )
249+ }
250+
251+ d .SetId (serverId )
252+ if err := waitingForCBHInstanceActive (ctx , client , d , d .Timeout (schema .TimeoutCreate )); err != nil {
253+ return diag .Errorf ("error waiting for CBH instance (%s) creation to active: %s" , d .Id (), err )
254+ }
255+ } else {
256+ instanceId , err := createCBHInstance (client , d , cfg )
257+ if err != nil {
258+ return diag .FromErr (err )
259+ }
260+
261+ if err := waitingForCBHInstanceActiveByInstanceID (ctx , client , instanceId , d , d .Timeout (schema .TimeoutCreate )); err != nil {
262+ return diag .Errorf ("error waiting for CBH instance (%s) creation to active: %s" , d .Id (), err )
263+ }
250264 }
251265
252266 // After successfully creating an instance using the first security group ID, check if it is necessary to update the
@@ -295,11 +309,17 @@ func createCBHInstance(client *golangsdk.ServiceClient, d *schema.ResourceData,
295309 return "" , err
296310 }
297311
298- orderId := utils .PathSearch ("order_id" , createInstanceRespBody , "" ).(string )
299- if orderId == "" {
300- return "" , fmt .Errorf ("unable to find the order ID of the CBH instance from the API response" )
312+ var targetId string
313+ if d .Get ("charging_mode" ).(string ) == "prePaid" {
314+ targetId = utils .PathSearch ("order_id" , createInstanceRespBody , "" ).(string )
315+ } else {
316+ targetId = utils .PathSearch ("instance_id" , createInstanceRespBody , "" ).(string )
301317 }
302- return orderId , nil
318+
319+ if targetId == "" {
320+ return "" , errors .New ("unable to find the order/instance ID of the CBH instance from the API response" )
321+ }
322+ return targetId , nil
303323}
304324
305325func buildCreateCBHInstanceBodyParam (d * schema.ResourceData , region string , epsId string , publicIp interface {}) map [string ]interface {} {
@@ -310,14 +330,16 @@ func buildCreateCBHInstanceBodyParam(d *schema.ResourceData, region string, epsI
310330 "region" : region ,
311331 "availability_zone" : d .Get ("availability_zone" ),
312332 "charging_mode" : buildCreateChargingModeParam (d ),
313- "period_type" : buildCreatePeriodTypeParam (d ),
314- "period_num" : utils .ValueIgnoreEmpty (d .Get ("period" )),
315- "is_auto_renew" : buildCreateIsAutoRenewParam (d ),
316- "is_auto_pay" : 1 ,
317333 "network" : buildCreateNetworkBodyParam (d , publicIp ),
318334 "attach_disk_size" : utils .ValueIgnoreEmpty (d .Get ("attach_disk_size" )),
319335 "enterprise_project_id" : utils .ValueIgnoreEmpty (epsId ),
320336 }
337+ if d .Get ("charging_mode" ).(string ) == "prePaid" {
338+ bodyParam ["period_type" ] = buildCreatePeriodTypeParam (d )
339+ bodyParam ["period_num" ] = utils .ValueIgnoreEmpty (d .Get ("period" ))
340+ bodyParam ["is_auto_renew" ] = buildCreateIsAutoRenewParam (d )
341+ bodyParam ["is_auto_pay" ] = 1
342+ }
321343 // The default value of the field `ipv6_enable` is false
322344 if d .Get ("ipv6_enable" ).(bool ) {
323345 bodyParam ["ipv6_enable" ] = true
@@ -335,6 +357,9 @@ func buildCreateChargingModeParam(d *schema.ResourceData) interface{} {
335357 if d .Get ("charging_mode" ).(string ) == "prePaid" {
336358 return 0
337359 }
360+ if d .Get ("charging_mode" ).(string ) == "postPaid" {
361+ return 1
362+ }
338363 return nil
339364}
340365
@@ -534,6 +559,48 @@ func waitingForCBHInstanceShutoff(ctx context.Context, client *golangsdk.Service
534559 return err
535560}
536561
562+ func waitingForCBHInstanceActiveByInstanceID (ctx context.Context , client * golangsdk.ServiceClient , instanceId string , d * schema.ResourceData ,
563+ timeout time.Duration ) error {
564+ expression := fmt .Sprintf ("[?instance_id == '%s']|[0]" , instanceId )
565+ unexpectedStatus := []string {"SHUTOFF" , "DELETING" , "DELETED" , "ERROR" , "FROZEN" }
566+ stateConf := & resource.StateChangeConf {
567+ Pending : []string {"PENDING" },
568+ Target : []string {"COMPLETED" },
569+ Refresh : func () (interface {}, string , error ) {
570+ instances , err := getCBHInstanceList (client )
571+ if err != nil {
572+ return nil , "ERROR" , err
573+ }
574+ instance := utils .PathSearch (expression , instances , nil )
575+ if instance == nil {
576+ return nil , "ERROR" , golangsdk.ErrDefault404 {}
577+ }
578+
579+ status := utils .PathSearch ("status_info.status" , instance , "" ).(string )
580+ if status == "ACTIVE" {
581+ serverId := utils .PathSearch ("server_id" , instance , "" ).(string )
582+ d .SetId (serverId )
583+ return instance , "COMPLETED" , nil
584+ }
585+
586+ if status == "" {
587+ return instance , "ERROR" , errors .New ("status is not found in list API response" )
588+ }
589+
590+ if utils .StrSliceContains (unexpectedStatus , status ) {
591+ return instance , status , nil
592+ }
593+ return instance , "PENDING" , nil
594+ },
595+ Timeout : timeout ,
596+ Delay : 10 * time .Second ,
597+ PollInterval : 10 * time .Second ,
598+ }
599+
600+ _ , err := stateConf .WaitForStateContext (ctx )
601+ return err
602+ }
603+
537604func waitingForCBHInstanceActive (ctx context.Context , client * golangsdk.ServiceClient , d * schema.ResourceData ,
538605 timeout time.Duration ) error {
539606 expression := fmt .Sprintf ("[?server_id == '%s']|[0]" , d .Id ())
@@ -557,7 +624,7 @@ func waitingForCBHInstanceActive(ctx context.Context, client *golangsdk.ServiceC
557624 }
558625
559626 if status == "" {
560- return instance , "ERROR" , fmt . Errorf ("status is not found in list API response" )
627+ return instance , "ERROR" , errors . New ("status is not found in list API response" )
561628 }
562629
563630 if utils .StrSliceContains (unexpectedStatus , status ) {
0 commit comments