Skip to content

Commit 7925d33

Browse files
Add Tool resource to product Dialgoflow CX (#14091) (#23192)
[upstream:01c115bb04f7dfaea6d09f236aa4881e7ee2b583] Signed-off-by: Modular Magician <[email protected]>
1 parent c5abf8e commit 7925d33

10 files changed

+2930
-2
lines changed

.changelog/14091.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:new-resource
2+
`google_dialogflow_cx_tool`
3+
```

google/provider/provider_mmv1_resources.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,9 +540,9 @@ var handwrittenIAMDatasources = map[string]*schema.Resource{
540540
}
541541

542542
// Resources
543-
// Generated resources: 617
543+
// Generated resources: 618
544544
// Generated IAM resources: 309
545-
// Total generated resources: 926
545+
// Total generated resources: 927
546546
var generatedResources = map[string]*schema.Resource{
547547
"google_folder_access_approval_settings": accessapproval.ResourceAccessApprovalFolderSettings(),
548548
"google_organization_access_approval_settings": accessapproval.ResourceAccessApprovalOrganizationSettings(),
@@ -994,6 +994,7 @@ var generatedResources = map[string]*schema.Resource{
994994
"google_dialogflow_cx_page": dialogflowcx.ResourceDialogflowCXPage(),
995995
"google_dialogflow_cx_security_settings": dialogflowcx.ResourceDialogflowCXSecuritySettings(),
996996
"google_dialogflow_cx_test_case": dialogflowcx.ResourceDialogflowCXTestCase(),
997+
"google_dialogflow_cx_tool": dialogflowcx.ResourceDialogflowCXTool(),
997998
"google_dialogflow_cx_version": dialogflowcx.ResourceDialogflowCXVersion(),
998999
"google_dialogflow_cx_webhook": dialogflowcx.ResourceDialogflowCXWebhook(),
9991000
"google_discovery_engine_chat_engine": discoveryengine.ResourceDiscoveryEngineChatEngine(),

google/services/dialogflowcx/resource_dialogflow_cx_agent.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,25 @@ These settings affect:
355355
Computed: true,
356356
Description: `Name of the start flow in this agent. A start flow will be automatically created when the agent is created, and can only be deleted by deleting the agent. Format: projects/<Project ID>/locations/<Location ID>/agents/<Agent ID>/flows/<Flow ID>.`,
357357
},
358+
"delete_chat_engine_on_destroy": {
359+
Type: schema.TypeBool,
360+
Optional: true,
361+
Description: `If set to 'true', Terraform will delete the chat engine associated with the agent when the agent is destroyed.
362+
Otherwise, the chat engine will persist.
363+
364+
This virtual field addresses a critical dependency chain: 'agent' -> 'engine' -> 'data store'. The chat engine is automatically
365+
provisioned when a data store is linked to the agent, meaning Terraform doesn't have direct control over its lifecycle as a managed
366+
resource. This creates a problem when both the agent and data store are managed by Terraform and need to be destroyed. Without
367+
delete_chat_engine_on_destroy set to true, the data store's deletion would fail because the unmanaged chat engine would still be
368+
using it. This setting ensures that the entire dependency chain can be properly torn down.
369+
See 'mmv1/templates/terraform/examples/dialogflowcx_tool_data_store.tf.tmpl' as an example.
370+
371+
Data store can be linked to an agent through the 'knowledgeConnectorSettings' field of a [flow](https://cloud.google.com/dialogflow/cx/docs/reference/rest/v3/projects.locations.agents.flows#resource:-flow)
372+
or a [page](https://cloud.google.com/dialogflow/cx/docs/reference/rest/v3/projects.locations.agents.flows.pages#resource:-page)
373+
or the 'dataStoreSpec' field of a [tool](https://cloud.google.com/dialogflow/cx/docs/reference/rest/v3/projects.locations.agents.tools#resource:-tool).
374+
The ID of the implicitly created engine is stored in the 'genAppBuilderSettings' field of the [agent](https://cloud.google.com/dialogflow/cx/docs/reference/rest/v3/projects.locations.agents#resource:-agent).`,
375+
Default: false,
376+
},
358377
"project": {
359378
Type: schema.TypeString,
360379
Optional: true,
@@ -549,6 +568,12 @@ func resourceDialogflowCXAgentRead(d *schema.ResourceData, meta interface{}) err
549568
return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("DialogflowCXAgent %q", d.Id()))
550569
}
551570

571+
// Explicitly set virtual fields to default values if unset
572+
if _, ok := d.GetOkExists("delete_chat_engine_on_destroy"); !ok {
573+
if err := d.Set("delete_chat_engine_on_destroy", false); err != nil {
574+
return fmt.Errorf("Error setting delete_chat_engine_on_destroy: %s", err)
575+
}
576+
}
552577
if err := d.Set("project", project); err != nil {
553578
return fmt.Errorf("Error reading Agent: %s", err)
554579
}
@@ -821,6 +846,26 @@ func resourceDialogflowCXAgentDelete(d *schema.ResourceData, meta interface{}) e
821846
}
822847

823848
headers := make(http.Header)
849+
// Extract engine ID from the gen_app_builder_settings field of the Agent
850+
s := d.Get("gen_app_builder_settings")
851+
log.Printf("[DEBUG] gen_app_builder_settings: %v", s)
852+
settings, ok := s.([]interface{})
853+
if !ok {
854+
return fmt.Errorf("Error converting gen_app_builder_settings %s to []interface{}", s)
855+
}
856+
857+
engineID := ""
858+
if len(settings) > 0 {
859+
// An engine is linked to the Agent. Delete it.
860+
engineIDIntf, ok := settings[0].(map[string]interface{})["engine"]
861+
if !ok {
862+
return fmt.Errorf("Expected key 'engine' in map %+v", settings[0])
863+
}
864+
engineID, ok = engineIDIntf.(string)
865+
if !ok {
866+
return fmt.Errorf("Can convert engine ID %s to string", engineIDIntf)
867+
}
868+
}
824869

825870
log.Printf("[DEBUG] Deleting Agent %q", d.Id())
826871
res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
@@ -837,6 +882,41 @@ func resourceDialogflowCXAgentDelete(d *schema.ResourceData, meta interface{}) e
837882
return transport_tpg.HandleNotFoundError(err, d, "Agent")
838883
}
839884

885+
if d.Get("delete_chat_engine_on_destroy").(bool) && engineID != "" {
886+
// Check if the engine exist.
887+
baseUrl, err := tpgresource.ReplaceVars(d, config, "{{DiscoveryEngineBasePath}}")
888+
if err != nil {
889+
return err
890+
}
891+
engineUrl := baseUrl + engineID
892+
_, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
893+
Config: config,
894+
Method: "GET",
895+
Project: project,
896+
RawURL: engineUrl,
897+
UserAgent: userAgent,
898+
})
899+
if err != nil {
900+
log.Printf("[DEBUG] engine %s doesn't exist. No need to delete", engineID)
901+
return nil
902+
}
903+
904+
// delete the engine
905+
log.Printf("[DEBUG] Deleting engine %v", engineID)
906+
_, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
907+
Config: config,
908+
Method: "DELETE",
909+
Project: project,
910+
RawURL: engineUrl,
911+
UserAgent: userAgent,
912+
Timeout: d.Timeout(schema.TimeoutDelete),
913+
})
914+
if err != nil {
915+
return fmt.Errorf("Error deleting engine %s: %s", engineID, err)
916+
}
917+
log.Printf("[DEBUG] Finished deleting engine %s", engineID)
918+
}
919+
840920
log.Printf("[DEBUG] Finished deleting Agent %q: %#v", d.Id(), res)
841921
return nil
842922
}
@@ -858,6 +938,11 @@ func resourceDialogflowCXAgentImport(d *schema.ResourceData, meta interface{}) (
858938
}
859939
d.SetId(id)
860940

941+
// Explicitly set virtual fields to default values on import
942+
if err := d.Set("delete_chat_engine_on_destroy", false); err != nil {
943+
return nil, fmt.Errorf("Error setting delete_chat_engine_on_destroy: %s", err)
944+
}
945+
861946
return []*schema.ResourceData{d}, nil
862947
}
863948

google/services/dialogflowcx/resource_dialogflow_cx_agent_generated_meta.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ fields:
1818
- field: 'advanced_settings.speech_settings.use_timeout_based_endpointing'
1919
- field: 'avatar_uri'
2020
- field: 'default_language_code'
21+
- field: 'delete_chat_engine_on_destroy'
22+
provider_only: true
2123
- field: 'description'
2224
- field: 'display_name'
2325
- field: 'enable_spell_correction'

0 commit comments

Comments
 (0)