@@ -27,6 +27,7 @@ import (
27
27
"time"
28
28
29
29
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
30
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
30
31
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
31
32
32
33
"github.com/hashicorp/terraform-provider-google/google/tpgresource"
@@ -70,6 +71,55 @@ func NotebooksInstanceKmsDiffSuppress(_, old, new string, _ *schema.ResourceData
70
71
return false
71
72
}
72
73
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
+
73
123
func ResourceNotebooksInstance () * schema.Resource {
74
124
return & schema.Resource {
75
125
Create : resourceNotebooksInstanceCreate ,
@@ -496,6 +546,12 @@ the population of this value.`,
496
546
Optional : true ,
497
547
Description : `Instance update time.` ,
498
548
},
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
+ },
499
555
"project" : {
500
556
Type : schema .TypeString ,
501
557
Optional : true ,
@@ -737,6 +793,20 @@ func resourceNotebooksInstanceCreate(d *schema.ResourceData, meta interface{}) e
737
793
}
738
794
d .SetId (id )
739
795
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
+
740
810
log .Printf ("[DEBUG] Finished creating Instance %q: %#v" , d .Id (), res )
741
811
742
812
return resourceNotebooksInstanceRead (d , meta )
@@ -778,6 +848,12 @@ func resourceNotebooksInstanceRead(d *schema.ResourceData, meta interface{}) err
778
848
return transport_tpg .HandleNotFoundError (err , d , fmt .Sprintf ("NotebooksInstance %q" , d .Id ()))
779
849
}
780
850
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
+ }
781
857
if err := d .Set ("project" , project ); err != nil {
782
858
return fmt .Errorf ("Error reading Instance: %s" , err )
783
859
}
@@ -972,6 +1048,27 @@ func resourceNotebooksInstanceUpdate(d *schema.ResourceData, meta interface{}) e
972
1048
973
1049
d .Partial (false )
974
1050
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
+ }
975
1072
return resourceNotebooksInstanceRead (d , meta )
976
1073
}
977
1074
@@ -1045,6 +1142,11 @@ func resourceNotebooksInstanceImport(d *schema.ResourceData, meta interface{}) (
1045
1142
}
1046
1143
d .SetId (id )
1047
1144
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
+
1048
1150
return []* schema.ResourceData {d }, nil
1049
1151
}
1050
1152
0 commit comments