@@ -27,6 +27,7 @@ import (
2727 "time"
2828
2929 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
30+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
3031 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
3132
3233 "github.com/hashicorp/terraform-provider-google-beta/google-beta/tpgresource"
@@ -70,6 +71,55 @@ func NotebooksInstanceKmsDiffSuppress(_, old, new string, _ *schema.ResourceData
7071 return false
7172}
7273
74+ // waitForNotebooksInstanceActive waits for an Notebook instance to become "ACTIVE"
75+ func waitForNotebooksInstanceActive (d * schema.ResourceData , config * transport_tpg.Config , timeout time.Duration ) error {
76+ return resource .Retry (timeout , func () * resource.RetryError {
77+ if err := resourceNotebooksInstanceRead (d , config ); err != nil {
78+ return resource .NonRetryableError (err )
79+ }
80+
81+ name := d .Get ("name" ).(string )
82+ state := d .Get ("state" ).(string )
83+ if state == "ACTIVE" {
84+ log .Printf ("[DEBUG] Notebook Instance %q has state %q." , name , state )
85+ return nil
86+ } else {
87+ return resource .RetryableError (fmt .Errorf ("Notebook Instance %q has state %q. Waiting for ACTIVE state" , name , state ))
88+ }
89+
90+ })
91+ }
92+
93+ func modifyNotebooksInstanceState (config * transport_tpg.Config , d * schema.ResourceData , project string , billingProject string , userAgent string , state string ) (map [string ]interface {}, error ) {
94+ url , err := tpgresource .ReplaceVars (d , config , "{{NotebooksBasePath}}projects/{{project}}/locations/{{location}}/instances/{{name}}:" + state )
95+ if err != nil {
96+ return nil , err
97+ }
98+
99+ res , err := transport_tpg .SendRequest (transport_tpg.SendRequestOptions {
100+ Config : config ,
101+ Method : "POST" ,
102+ Project : billingProject ,
103+ RawURL : url ,
104+ UserAgent : userAgent ,
105+ })
106+ if err != nil {
107+ return nil , fmt .Errorf ("Unable to %q google_notebooks_instance %q: %s" , state , d .Id (), err )
108+ }
109+ return res , nil
110+ }
111+
112+ func waitForNotebooksOperation (config * transport_tpg.Config , d * schema.ResourceData , project string , billingProject string , userAgent string , response map [string ]interface {}) error {
113+ var opRes map [string ]interface {}
114+ err := NotebooksOperationWaitTimeWithResponse (
115+ config , response , & opRes , project , "Modifying Notebook Instance state" , userAgent ,
116+ d .Timeout (schema .TimeoutUpdate ))
117+ if err != nil {
118+ return err
119+ }
120+ return nil
121+ }
122+
73123func ResourceNotebooksInstance () * schema.Resource {
74124 return & schema.Resource {
75125 Create : resourceNotebooksInstanceCreate ,
@@ -496,6 +546,12 @@ the population of this value.`,
496546 Optional : true ,
497547 Description : `Instance update time.` ,
498548 },
549+ "desired_state" : {
550+ Type : schema .TypeString ,
551+ Optional : true ,
552+ Default : "ACTIVE" ,
553+ Description : `Desired state of the Notebook Instance. Set this field to 'ACTIVE' to start the Instance, and 'STOPPED' to stop the Instance.` ,
554+ },
499555 "project" : {
500556 Type : schema .TypeString ,
501557 Optional : true ,
@@ -737,6 +793,20 @@ func resourceNotebooksInstanceCreate(d *schema.ResourceData, meta interface{}) e
737793 }
738794 d .SetId (id )
739795
796+ if err := waitForNotebooksInstanceActive (d , config , d .Timeout (schema .TimeoutCreate )- time .Minute ); err != nil {
797+ return fmt .Errorf ("Notebook instance %q did not reach ACTIVE state: %q" , d .Get ("name" ).(string ), err )
798+ }
799+
800+ if p , ok := d .GetOk ("desired_state" ); ok && p .(string ) == "STOPPED" {
801+ dRes , err := modifyNotebooksInstanceState (config , d , project , billingProject , userAgent , "stop" )
802+ if err != nil {
803+ return err
804+ }
805+ if err := waitForNotebooksOperation (config , d , project , billingProject , userAgent , dRes ); err != nil {
806+ return fmt .Errorf ("Error stopping Notebook Instance: %s" , err )
807+ }
808+ }
809+
740810 log .Printf ("[DEBUG] Finished creating Instance %q: %#v" , d .Id (), res )
741811
742812 return resourceNotebooksInstanceRead (d , meta )
@@ -778,6 +848,12 @@ func resourceNotebooksInstanceRead(d *schema.ResourceData, meta interface{}) err
778848 return transport_tpg .HandleNotFoundError (err , d , fmt .Sprintf ("NotebooksInstance %q" , d .Id ()))
779849 }
780850
851+ // Explicitly set virtual fields to default values if unset
852+ if _ , ok := d .GetOkExists ("desired_state" ); ! ok {
853+ if err := d .Set ("desired_state" , "ACTIVE" ); err != nil {
854+ return fmt .Errorf ("Error setting desired_state: %s" , err )
855+ }
856+ }
781857 if err := d .Set ("project" , project ); err != nil {
782858 return fmt .Errorf ("Error reading Instance: %s" , err )
783859 }
@@ -972,6 +1048,27 @@ func resourceNotebooksInstanceUpdate(d *schema.ResourceData, meta interface{}) e
9721048
9731049 d .Partial (false )
9741050
1051+ name := d .Get ("name" ).(string )
1052+ state := d .Get ("state" ).(string )
1053+ desired_state := d .Get ("desired_state" ).(string )
1054+
1055+ if state != desired_state {
1056+ verb := "start"
1057+ if desired_state == "STOPPED" {
1058+ verb = "stop"
1059+ }
1060+ pRes , err := modifyNotebooksInstanceState (config , d , project , billingProject , userAgent , verb )
1061+ if err != nil {
1062+ return err
1063+ }
1064+
1065+ if err := waitForNotebooksOperation (config , d , project , billingProject , userAgent , pRes ); err != nil {
1066+ return fmt .Errorf ("Error waiting to modify Notebook Instance state: %s" , err )
1067+ }
1068+
1069+ } else {
1070+ log .Printf ("[DEBUG] Notebook Instance %q has state %q." , name , state )
1071+ }
9751072 return resourceNotebooksInstanceRead (d , meta )
9761073}
9771074
@@ -1045,6 +1142,11 @@ func resourceNotebooksInstanceImport(d *schema.ResourceData, meta interface{}) (
10451142 }
10461143 d .SetId (id )
10471144
1145+ // Explicitly set virtual fields to default values on import
1146+ if err := d .Set ("desired_state" , "ACTIVE" ); err != nil {
1147+ return nil , fmt .Errorf ("Error setting desired_state: %s" , err )
1148+ }
1149+
10481150 return []* schema.ResourceData {d }, nil
10491151}
10501152
0 commit comments