Skip to content

Commit 662bf91

Browse files
authored
Set granular update mask for Dialogflow cx playbook instruction; (#15702)
1 parent 1a40af1 commit 662bf91

File tree

4 files changed

+207
-4
lines changed

4 files changed

+207
-4
lines changed

mmv1/products/dialogflowcx/Playbook.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ update_mask: true
3131
custom_code:
3232
pre_create: 'templates/terraform/pre_create/dialogflow_set_location.go.tmpl'
3333
pre_read: 'templates/terraform/pre_create/dialogflow_set_location.go.tmpl'
34-
pre_update: 'templates/terraform/pre_create/dialogflow_set_location.go.tmpl'
34+
pre_update: 'templates/terraform/pre_update/dialogflowcx_playbook_granular_update_mask.go.tmpl'
3535
pre_delete: 'templates/terraform/pre_create/dialogflow_set_location.go.tmpl'
3636
custom_import: 'templates/terraform/custom_import/dialogflowcx_playbook.go.tmpl'
3737

mmv1/templates/terraform/pre_create/dialogflow_set_location.go.tmpl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ if parts := regexp.MustCompile(`locations\/([^\/]*)\/`).FindStringSubmatch(d.Get
1212
}
1313

1414
// only insert location into url if the base_url in products/dialogflowcx/product.yaml is used
15-
if strings.HasPrefix(url, "https://-dialogflow.googleapis.com/v3/") || strings.HasPrefix(url, "https://-dialogflow.googleapis.com/v3beta1/") {
16-
url = strings.Replace(url, "-dialogflow", fmt.Sprintf("%s-dialogflow", location), 1)
15+
if strings.HasPrefix(url, "https://-dialogflow.googleapis.com/v3/") ||
16+
strings.HasPrefix(url, "https://-dialogflow." + config.UniverseDomain + "/v3/") ||
17+
strings.HasPrefix(url, "https://-dialogflow.googleapis.com/v3beta1/") ||
18+
strings.HasPrefix(url, "https://-dialogflow." + config.UniverseDomain + "/v3beta1/") {
19+
url = strings.Replace(url, "https://-dialogflow", fmt.Sprintf("https://%s-dialogflow", location), 1)
1720
}
18-
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// extract location from the parent
2+
location := ""
3+
4+
if parts := regexp.MustCompile(`locations\/([^\/]*)\/`).FindStringSubmatch(d.Get("parent").(string)); parts != nil {
5+
location = parts[1]
6+
} else {
7+
return fmt.Errorf(
8+
"Saw %s when the parent is expected to contains location %s",
9+
d.Get("parent"),
10+
"projects/{{"{{"}}project{{"}}"}}/locations/{{"{{"}}location{{"}}"}}/...",
11+
)
12+
}
13+
14+
// only insert location into url if the base_url in products/dialogflowcx/product.yaml is used
15+
if strings.HasPrefix(url, "https://-dialogflow.googleapis.com/v3/") ||
16+
strings.HasPrefix(url, "https://-dialogflow." + config.UniverseDomain + "/v3/") ||
17+
strings.HasPrefix(url, "https://-dialogflow.googleapis.com/v3beta1/") ||
18+
strings.HasPrefix(url, "https://-dialogflow." + config.UniverseDomain + "/v3beta1/") {
19+
url = strings.Replace(url, "https://-dialogflow", fmt.Sprintf("https://%s-dialogflow", location), 1)
20+
}
21+
22+
// The generated code sets the wrong masks for the following fields.
23+
newUpdateMask := []string{}
24+
if d.HasChange("instruction.0.steps") {
25+
newUpdateMask = append(newUpdateMask, "instruction.steps")
26+
}
27+
if d.HasChange("instruction.0.guidelines") {
28+
newUpdateMask = append(newUpdateMask, "instruction.guidelines")
29+
}
30+
// Pull out any other set fields from the generated mask.
31+
for _, mask := range updateMask {
32+
if mask == "instruction" {
33+
continue
34+
}
35+
newUpdateMask = append(newUpdateMask, mask)
36+
}
37+
// Overwrite the previously set mask.
38+
url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(newUpdateMask, ",")})
39+
if err != nil {
40+
return err
41+
}
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
package dialogflowcx_test
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"strconv"
7+
"strings"
8+
"testing"
9+
"time"
10+
11+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
12+
"github.com/hashicorp/terraform-plugin-testing/terraform"
13+
14+
"github.com/hashicorp/terraform-provider-google/google/acctest"
15+
"github.com/hashicorp/terraform-provider-google/google/envvar"
16+
"github.com/hashicorp/terraform-provider-google/google/tpgresource"
17+
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
18+
19+
"google.golang.org/api/googleapi"
20+
)
21+
22+
var (
23+
_ = fmt.Sprintf
24+
_ = log.Print
25+
_ = strconv.Atoi
26+
_ = strings.Trim
27+
_ = time.Now
28+
_ = resource.TestMain
29+
_ = terraform.NewState
30+
_ = envvar.TestEnvVar
31+
_ = tpgresource.SetLabels
32+
_ = transport_tpg.Config{}
33+
_ = googleapi.Error{}
34+
)
35+
36+
func TestAccDialogflowCXPlaybook_dialogflowcxPlaybookBasicExample_update(t *testing.T) {
37+
t.Parallel()
38+
39+
context := map[string]interface{}{
40+
"random_suffix": acctest.RandString(t, 10),
41+
}
42+
43+
acctest.VcrTest(t, resource.TestCase{
44+
PreCheck: func() { acctest.AccTestPreCheck(t) },
45+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
46+
CheckDestroy: testAccCheckDialogflowCXPlaybookDestroyProducer(t),
47+
Steps: []resource.TestStep{
48+
{
49+
Config: testAccDialogflowCXPlaybook_dialogflowcxPlaybookBasicExample_basic(context),
50+
},
51+
{
52+
ResourceName: "google_dialogflow_cx_playbook.my-playbook",
53+
ImportState: true,
54+
ImportStateVerify: true,
55+
ImportStateVerifyIgnore: []string{"parent", "playbook_type"},
56+
},
57+
{
58+
Config: testAccDialogflowCXPlaybook_dialogflowcxPlaybookBasicExample_update(context),
59+
},
60+
{
61+
ResourceName: "google_dialogflow_cx_playbook.my-playbook",
62+
ImportState: true,
63+
ImportStateVerify: true,
64+
ImportStateVerifyIgnore: []string{"parent", "playbook_type"},
65+
},
66+
},
67+
})
68+
}
69+
70+
func testAccDialogflowCXPlaybook_dialogflowcxPlaybookBasicExample_basic(context map[string]interface{}) string {
71+
return acctest.Nprintf(`
72+
resource "google_dialogflow_cx_agent" "agent" {
73+
display_name = "tf-test-dialogflowcx-agent-basic%{random_suffix}"
74+
location = "global"
75+
default_language_code = "en"
76+
time_zone = "America/New_York"
77+
description = "Example description."
78+
}
79+
80+
resource "google_dialogflow_cx_playbook" "my-playbook" {
81+
parent = google_dialogflow_cx_agent.agent.id
82+
display_name = "Example Display Name"
83+
goal = "Example Goal"
84+
playbook_type = "ROUTINE"
85+
instruction {
86+
steps {
87+
text = "step 1"
88+
steps = jsonencode([
89+
{
90+
"text": "step 1 1"
91+
},
92+
{
93+
"text": "step 1 2",
94+
"steps": [
95+
{
96+
"text": "step 1 2 1"
97+
},
98+
{
99+
"text": "step 1 2 2"
100+
}
101+
]
102+
},
103+
{
104+
"text": "step 1 3"
105+
}
106+
])
107+
}
108+
steps {
109+
text = "step 2"
110+
}
111+
steps {
112+
text = "step 3"
113+
}
114+
}
115+
}
116+
`, context)
117+
}
118+
119+
func testAccDialogflowCXPlaybook_dialogflowcxPlaybookBasicExample_update(context map[string]interface{}) string {
120+
return acctest.Nprintf(`
121+
resource "google_dialogflow_cx_agent" "agent" {
122+
display_name = "tf-test-dialogflowcx-agent-basic%{random_suffix}"
123+
location = "global"
124+
default_language_code = "en"
125+
time_zone = "America/New_York"
126+
description = "Example description."
127+
}
128+
129+
resource "google_dialogflow_cx_playbook" "my-playbook" {
130+
parent = google_dialogflow_cx_agent.agent.id
131+
display_name = "Example Display Name"
132+
goal = "Example Goal"
133+
playbook_type = "ROUTINE"
134+
instruction {
135+
steps {
136+
text = "step 1"
137+
steps = jsonencode([
138+
{
139+
"text": "step 1 1"
140+
},
141+
{
142+
"text": "step 1 2",
143+
"steps": [
144+
{
145+
"text": "step 1 2 1"
146+
},
147+
{
148+
"text": "step 1 2 2"
149+
}
150+
]
151+
},
152+
{
153+
"text": "step 1 3"
154+
}
155+
])
156+
}
157+
}
158+
}
159+
`, context)
160+
}

0 commit comments

Comments
 (0)