3434 _ resource.Resource = & tokenResource {}
3535 _ resource.ResourceWithConfigure = & tokenResource {}
3636 _ resource.ResourceWithImportState = & tokenResource {}
37+ _ resource.ResourceWithModifyPlan = & tokenResource {}
3738)
3839
3940const (
@@ -110,13 +111,10 @@ func (r *tokenResource) Configure(
110111 )
111112 apiClient , err = modelserving .NewAPIClient (
112113 config .WithCustomAuth (providerData .RoundTripper ),
113- config .WithEndpoint (providerData .ModelServingCustomEndpoint ),
114- config .WithRegion (providerData .GetRegion ()),
115114 )
116115 } else {
117116 apiClient , err = modelserving .NewAPIClient (
118117 config .WithCustomAuth (providerData .RoundTripper ),
119- config .WithRegion (providerData .GetRegion ()),
120118 )
121119 }
122120 if err != nil {
@@ -141,7 +139,6 @@ func (r *tokenResource) Configure(
141139 } else {
142140 serviceEnablementClient , err = serviceenablement .NewAPIClient (
143141 config .WithCustomAuth (providerData .RoundTripper ),
144- config .WithRegion (providerData .GetRegion ()),
145142 )
146143 }
147144 if err != nil {
@@ -163,6 +160,49 @@ func (r *tokenResource) Configure(
163160 tflog .Info (ctx , "Model-Serving auth token client configured" )
164161}
165162
163+ // ModifyPlan implements resource.ResourceWithModifyPlan.
164+ // Use the modifier to set the effective region in the current plan.
165+ //
166+ //nolint:gocritic // function signature required by Terraform
167+ func (r * tokenResource ) ModifyPlan (
168+ ctx context.Context ,
169+ req resource.ModifyPlanRequest ,
170+ resp * resource.ModifyPlanResponse ,
171+ ) {
172+ var configModel Model
173+
174+ // skip initial empty configuration to avoid follow-up errors
175+ if req .Config .Raw .IsNull () {
176+ return
177+ }
178+ resp .Diagnostics .Append (req .Config .Get (ctx , & configModel )... )
179+ if resp .Diagnostics .HasError () {
180+ return
181+ }
182+
183+ var planModel Model
184+ resp .Diagnostics .Append (req .Plan .Get (ctx , & planModel )... )
185+ if resp .Diagnostics .HasError () {
186+ return
187+ }
188+
189+ utils .AdaptRegion (
190+ ctx ,
191+ configModel .Region ,
192+ & planModel .Region ,
193+ r .providerData .GetRegion (),
194+ resp ,
195+ )
196+ if resp .Diagnostics .HasError () {
197+ return
198+ }
199+
200+ resp .Diagnostics .Append (resp .Plan .Set (ctx , planModel )... )
201+ if resp .Diagnostics .HasError () {
202+ return
203+ }
204+ }
205+
166206// Schema defines the schema for the resource.
167207func (r * tokenResource ) Schema (
168208 _ context.Context ,
@@ -272,7 +312,7 @@ func (r *tokenResource) Create(
272312 ctx = tflog .SetField (ctx , "region" , region )
273313
274314 // If model serving is not enabled, enable it
275- err := r .serviceEnablementClient .EnableService (ctx , projectId , utils .ModelServingServiceId ).
315+ err := r .serviceEnablementClient .EnableServiceRegional (ctx , region , projectId , utils .ModelServingServiceId ).
276316 Execute ()
277317 if err != nil {
278318 core .LogAndAddError (
@@ -284,7 +324,7 @@ func (r *tokenResource) Create(
284324 return
285325 }
286326
287- _ , err = serviceEnablementWait .EnableServiceWaitHandler (ctx , r .serviceEnablementClient , projectId , utils .ModelServingServiceId ).
327+ _ , err = serviceEnablementWait .EnableServiceWaitHandler (ctx , r .serviceEnablementClient , region , projectId , utils .ModelServingServiceId ).
288328 WaitWithContext (ctx )
289329 if err != nil {
290330 core .LogAndAddError (
@@ -335,7 +375,7 @@ func (r *tokenResource) Create(
335375 }
336376
337377 // Map response body to schema
338- err = mapCreateResponse (createTokenResp , waitResp , & model )
378+ err = mapCreateResponse (createTokenResp , waitResp , & model , region )
339379 if err != nil {
340380 core .LogAndAddError (
341381 ctx ,
@@ -630,7 +670,8 @@ func (r *tokenResource) ImportState(
630670 resp * resource.ImportStateResponse ,
631671) {
632672 idParts := strings .Split (req .ID , core .Separator )
633- if len (idParts ) != 2 || idParts [0 ] == "" || idParts [1 ] == "" {
673+ if len (idParts ) != 3 || idParts [0 ] == "" || idParts [1 ] == "" ||
674+ idParts [2 ] == "" {
634675 core .LogAndAddError (
635676 ctx ,
636677 & resp .Diagnostics ,
@@ -646,7 +687,9 @@ func (r *tokenResource) ImportState(
646687 resp .Diagnostics .Append (
647688 resp .State .SetAttribute (ctx , path .Root ("project_id" ), idParts [0 ])... )
648689 resp .Diagnostics .Append (
649- resp .State .SetAttribute (ctx , path .Root ("token_id" ), idParts [1 ])... )
690+ resp .State .SetAttribute (ctx , path .Root ("region" ), idParts [1 ])... )
691+ resp .Diagnostics .Append (
692+ resp .State .SetAttribute (ctx , path .Root ("token_id" ), idParts [2 ])... )
650693
651694 tflog .Info (ctx , "Model-Serving auth token state imported" )
652695}
@@ -655,6 +698,7 @@ func mapCreateResponse(
655698 tokenCreateResp * modelserving.CreateTokenResponse ,
656699 waitResp * modelserving.GetTokenResponse ,
657700 model * Model ,
701+ region string ,
658702) error {
659703 if tokenCreateResp == nil || tokenCreateResp .Token == nil {
660704 return fmt .Errorf ("response input is nil" )
@@ -669,9 +713,9 @@ func mapCreateResponse(
669713 return fmt .Errorf ("token id not present" )
670714 }
671715
672- validUntil := time . Now (). Format ( time . RFC3339 )
716+ validUntil := types . StringNull ( )
673717 if token .ValidUntil != nil {
674- validUntil = token .ValidUntil .Format (time .RFC3339 )
718+ validUntil = types . StringValue ( token .ValidUntil .Format (time .RFC3339 ) )
675719 }
676720
677721 if waitResp == nil || waitResp .Token == nil || waitResp .Token .State == nil {
@@ -680,6 +724,7 @@ func mapCreateResponse(
680724
681725 idParts := []string {
682726 model .ProjectId .ValueString (),
727+ region ,
683728 * tokenCreateResp .Token .Id ,
684729 }
685730 model .Id = types .StringValue (
@@ -688,14 +733,17 @@ func mapCreateResponse(
688733 model .TokenId = types .StringPointerValue (token .Id )
689734 model .Name = types .StringPointerValue (token .Name )
690735 model .State = types .StringPointerValue (waitResp .Token .State )
691- model .ValidUntil = types . StringValue ( validUntil )
736+ model .ValidUntil = validUntil
692737 model .Content = types .StringPointerValue (token .Content )
693738 model .Description = types .StringPointerValue (token .Description )
694739
695740 return nil
696741}
697742
698- func mapToken (token * modelserving.Token , model , state * Model ) error {
743+ func mapToken (
744+ token * modelserving.Token ,
745+ model , state * Model ,
746+ ) error {
699747 if token == nil {
700748 return fmt .Errorf ("response input is nil" )
701749 }
@@ -707,13 +755,14 @@ func mapToken(token *modelserving.Token, model, state *Model) error {
707755 }
708756
709757 // theoretically, should never happen, but still catch null pointers
710- validUntil := time . Now (). Format ( time . RFC3339 )
758+ validUntil := types . StringNull ( )
711759 if token .ValidUntil != nil {
712- validUntil = token .ValidUntil .Format (time .RFC3339 )
760+ validUntil = types . StringValue ( token .ValidUntil .Format (time .RFC3339 ) )
713761 }
714762
715763 idParts := []string {
716764 model .ProjectId .ValueString (),
765+ model .Region .ValueString (),
717766 model .TokenId .ValueString (),
718767 }
719768 model .Id = types .StringValue (
@@ -722,7 +771,7 @@ func mapToken(token *modelserving.Token, model, state *Model) error {
722771 model .TokenId = types .StringPointerValue (token .Id )
723772 model .Name = types .StringPointerValue (token .Name )
724773 model .State = types .StringPointerValue (token .State )
725- model .ValidUntil = types . StringValue ( validUntil )
774+ model .ValidUntil = validUntil
726775 model .Description = types .StringPointerValue (token .Description )
727776 model .Content = state .Content
728777
0 commit comments