diff --git a/.changelog/3285.txt b/.changelog/3285.txt new file mode 100644 index 0000000000..db7c5a64c5 --- /dev/null +++ b/.changelog/3285.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +`google_dialogflow_intent` +``` diff --git a/google-beta/provider.go b/google-beta/provider.go index 25716495c2..1e3e5fa093 100644 --- a/google-beta/provider.go +++ b/google-beta/provider.go @@ -595,9 +595,9 @@ func Provider() terraform.ResourceProvider { return provider } -// Generated resources: 138 +// Generated resources: 139 // Generated IAM resources: 54 -// Total generated resources: 192 +// Total generated resources: 193 func ResourceMap() map[string]*schema.Resource { resourceMap, _ := ResourceMapWithErrors() return resourceMap @@ -705,6 +705,7 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) { "google_datastore_index": resourceDatastoreIndex(), "google_deployment_manager_deployment": resourceDeploymentManagerDeployment(), "google_dialogflow_agent": resourceDialogflowAgent(), + "google_dialogflow_intent": resourceDialogflowIntent(), "google_dns_managed_zone": resourceDNSManagedZone(), "google_dns_policy": resourceDNSPolicy(), "google_filestore_instance": resourceFilestoreInstance(), diff --git a/google-beta/resource_dialogflow_intent.go b/google-beta/resource_dialogflow_intent.go new file mode 100644 index 0000000000..3bb09431ed --- /dev/null +++ b/google-beta/resource_dialogflow_intent.go @@ -0,0 +1,620 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "log" + "reflect" + "strconv" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" +) + +func resourceDialogflowIntent() *schema.Resource { + return &schema.Resource{ + Create: resourceDialogflowIntentCreate, + Read: resourceDialogflowIntentRead, + Update: resourceDialogflowIntentUpdate, + Delete: resourceDialogflowIntentDelete, + + Importer: &schema.ResourceImporter{ + State: resourceDialogflowIntentImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(4 * time.Minute), + Update: schema.DefaultTimeout(4 * time.Minute), + Delete: schema.DefaultTimeout(4 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "display_name": { + Type: schema.TypeString, + Required: true, + Description: `The name of this intent to be displayed on the console.`, + }, + "action": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Description: `The name of the action associated with the intent. +Note: The action name must not contain whitespaces.`, + }, + "default_response_platforms": { + Type: schema.TypeList, + Optional: true, + Description: `The list of platforms for which the first responses will be copied from the messages in PLATFORM_UNSPECIFIED +(i.e. default platform).`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "events": { + Type: schema.TypeList, + Optional: true, + Description: `The collection of event names that trigger the intent. If the collection of input contexts is not empty, all of +the contexts must be present in the active user session for an event to trigger this intent. See the +[events reference](https://cloud.google.com/dialogflow/docs/events-overview) for more details.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "input_context_names": { + Type: schema.TypeList, + Optional: true, + Description: `The list of context names required for this intent to be triggered. +Format: projects//agent/sessions/-/contexts/.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "is_fallback": { + Type: schema.TypeBool, + Computed: true, + Optional: true, + Description: `Indicates whether this is a fallback intent.`, + }, + "ml_disabled": { + Type: schema.TypeBool, + Computed: true, + Optional: true, + Description: `Indicates whether Machine Learning is disabled for the intent. +Note: If mlDisabled setting is set to true, then this intent is not taken into account during inference in ML +ONLY match mode. Also, auto-markup in the UI is turned off.`, + }, + "parent_followup_intent_name": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ForceNew: true, + Description: `The unique identifier of the parent intent in the chain of followup intents. +Format: projects//agent/intents/.`, + }, + "priority": { + Type: schema.TypeInt, + Computed: true, + Optional: true, + Description: `The priority of this intent. Higher numbers represent higher priorities. + - If the supplied value is unspecified or 0, the service translates the value to 500,000, which corresponds + to the Normal priority in the console. + - If the supplied value is negative, the intent is ignored in runtime detect intent requests.`, + }, + "reset_contexts": { + Type: schema.TypeBool, + Computed: true, + Optional: true, + Description: `Indicates whether to delete all contexts in the current session when this intent is matched.`, + }, + "webhook_state": { + Type: schema.TypeString, + Computed: true, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"WEBHOOK_STATE_ENABLED", "WEBHOOK_STATE_ENABLED_FOR_SLOT_FILLING", ""}, false), + Description: `Indicates whether webhooks are enabled for the intent. +* WEBHOOK_STATE_ENABLED: Webhook is enabled in the agent and in the intent. +* WEBHOOK_STATE_ENABLED_FOR_SLOT_FILLING: Webhook is enabled in the agent and in the intent. Also, each slot +filling prompt is forwarded to the webhook.`, + }, + "followup_intent_info": { + Type: schema.TypeList, + Computed: true, + Description: `Information about all followup intents that have this intent as a direct or indirect parent. We populate this field +only in the output.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "followup_intent_name": { + Type: schema.TypeString, + Optional: true, + Description: `The unique identifier of the followup intent. +Format: projects//agent/intents/.`, + }, + "parent_followup_intent_name": { + Type: schema.TypeString, + Optional: true, + Description: `The unique identifier of the followup intent's parent. +Format: projects//agent/intents/.`, + }, + }, + }, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: `The unique identifier of this intent. +Format: projects//agent/intents/.`, + }, + "root_followup_intent_name": { + Type: schema.TypeString, + Computed: true, + Description: `The unique identifier of the root intent in the chain of followup intents. It identifies the correct followup +intents chain for this intent. +Format: projects//agent/intents/.`, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + } +} + +func resourceDialogflowIntentCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + obj := make(map[string]interface{}) + displayNameProp, err := expandDialogflowIntentDisplayName(d.Get("display_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("display_name"); !isEmptyValue(reflect.ValueOf(displayNameProp)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { + obj["displayName"] = displayNameProp + } + webhookStateProp, err := expandDialogflowIntentWebhookState(d.Get("webhook_state"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("webhook_state"); !isEmptyValue(reflect.ValueOf(webhookStateProp)) && (ok || !reflect.DeepEqual(v, webhookStateProp)) { + obj["webhookState"] = webhookStateProp + } + priorityProp, err := expandDialogflowIntentPriority(d.Get("priority"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("priority"); !isEmptyValue(reflect.ValueOf(priorityProp)) && (ok || !reflect.DeepEqual(v, priorityProp)) { + obj["priority"] = priorityProp + } + isFallbackProp, err := expandDialogflowIntentIsFallback(d.Get("is_fallback"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("is_fallback"); !isEmptyValue(reflect.ValueOf(isFallbackProp)) && (ok || !reflect.DeepEqual(v, isFallbackProp)) { + obj["isFallback"] = isFallbackProp + } + mlDisabledProp, err := expandDialogflowIntentMlDisabled(d.Get("ml_disabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("ml_disabled"); !isEmptyValue(reflect.ValueOf(mlDisabledProp)) && (ok || !reflect.DeepEqual(v, mlDisabledProp)) { + obj["mlDisabled"] = mlDisabledProp + } + inputContextNamesProp, err := expandDialogflowIntentInputContextNames(d.Get("input_context_names"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("input_context_names"); !isEmptyValue(reflect.ValueOf(inputContextNamesProp)) && (ok || !reflect.DeepEqual(v, inputContextNamesProp)) { + obj["inputContextNames"] = inputContextNamesProp + } + eventsProp, err := expandDialogflowIntentEvents(d.Get("events"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("events"); !isEmptyValue(reflect.ValueOf(eventsProp)) && (ok || !reflect.DeepEqual(v, eventsProp)) { + obj["events"] = eventsProp + } + actionProp, err := expandDialogflowIntentAction(d.Get("action"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("action"); !isEmptyValue(reflect.ValueOf(actionProp)) && (ok || !reflect.DeepEqual(v, actionProp)) { + obj["action"] = actionProp + } + resetContextsProp, err := expandDialogflowIntentResetContexts(d.Get("reset_contexts"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("reset_contexts"); !isEmptyValue(reflect.ValueOf(resetContextsProp)) && (ok || !reflect.DeepEqual(v, resetContextsProp)) { + obj["resetContexts"] = resetContextsProp + } + defaultResponsePlatformsProp, err := expandDialogflowIntentDefaultResponsePlatforms(d.Get("default_response_platforms"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("default_response_platforms"); !isEmptyValue(reflect.ValueOf(defaultResponsePlatformsProp)) && (ok || !reflect.DeepEqual(v, defaultResponsePlatformsProp)) { + obj["defaultResponsePlatforms"] = defaultResponsePlatformsProp + } + parentFollowupIntentNameProp, err := expandDialogflowIntentParentFollowupIntentName(d.Get("parent_followup_intent_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("parent_followup_intent_name"); !isEmptyValue(reflect.ValueOf(parentFollowupIntentNameProp)) && (ok || !reflect.DeepEqual(v, parentFollowupIntentNameProp)) { + obj["parentFollowupIntentName"] = parentFollowupIntentNameProp + } + + url, err := replaceVars(d, config, "{{DialogflowBasePath}}projects/{{project}}/agent/intents/") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new Intent: %#v", obj) + project, err := getProject(d, config) + if err != nil { + return err + } + res, err := sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error creating Intent: %s", err) + } + if err := d.Set("name", flattenDialogflowIntentName(res["name"], d, config)); err != nil { + return fmt.Errorf(`Error setting computed identity field "name": %s`, err) + } + + // Store the ID now + id, err := replaceVars(d, config, "{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating Intent %q: %#v", d.Id(), res) + + // `name` is autogenerated from the api so needs to be set post-create + name, ok := res["name"] + if !ok { + return fmt.Errorf("Create response didn't contain critical fields. Create may not have succeeded.") + } + d.Set("name", name.(string)) + d.SetId(name.(string)) + + return resourceDialogflowIntentRead(d, meta) +} + +func resourceDialogflowIntentRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + url, err := replaceVars(d, config, "{{DialogflowBasePath}}{{name}}") + if err != nil { + return err + } + + project, err := getProject(d, config) + if err != nil { + return err + } + res, err := sendRequest(config, "GET", project, url, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("DialogflowIntent %q", d.Id())) + } + + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading Intent: %s", err) + } + + if err := d.Set("name", flattenDialogflowIntentName(res["name"], d, config)); err != nil { + return fmt.Errorf("Error reading Intent: %s", err) + } + if err := d.Set("display_name", flattenDialogflowIntentDisplayName(res["displayName"], d, config)); err != nil { + return fmt.Errorf("Error reading Intent: %s", err) + } + if err := d.Set("webhook_state", flattenDialogflowIntentWebhookState(res["webhookState"], d, config)); err != nil { + return fmt.Errorf("Error reading Intent: %s", err) + } + if err := d.Set("priority", flattenDialogflowIntentPriority(res["priority"], d, config)); err != nil { + return fmt.Errorf("Error reading Intent: %s", err) + } + if err := d.Set("is_fallback", flattenDialogflowIntentIsFallback(res["isFallback"], d, config)); err != nil { + return fmt.Errorf("Error reading Intent: %s", err) + } + if err := d.Set("ml_disabled", flattenDialogflowIntentMlDisabled(res["mlDisabled"], d, config)); err != nil { + return fmt.Errorf("Error reading Intent: %s", err) + } + if err := d.Set("input_context_names", flattenDialogflowIntentInputContextNames(res["inputContextNames"], d, config)); err != nil { + return fmt.Errorf("Error reading Intent: %s", err) + } + if err := d.Set("events", flattenDialogflowIntentEvents(res["events"], d, config)); err != nil { + return fmt.Errorf("Error reading Intent: %s", err) + } + if err := d.Set("action", flattenDialogflowIntentAction(res["action"], d, config)); err != nil { + return fmt.Errorf("Error reading Intent: %s", err) + } + if err := d.Set("reset_contexts", flattenDialogflowIntentResetContexts(res["resetContexts"], d, config)); err != nil { + return fmt.Errorf("Error reading Intent: %s", err) + } + if err := d.Set("default_response_platforms", flattenDialogflowIntentDefaultResponsePlatforms(res["defaultResponsePlatforms"], d, config)); err != nil { + return fmt.Errorf("Error reading Intent: %s", err) + } + if err := d.Set("root_followup_intent_name", flattenDialogflowIntentRootFollowupIntentName(res["rootFollowupIntentName"], d, config)); err != nil { + return fmt.Errorf("Error reading Intent: %s", err) + } + if err := d.Set("parent_followup_intent_name", flattenDialogflowIntentParentFollowupIntentName(res["parentFollowupIntentName"], d, config)); err != nil { + return fmt.Errorf("Error reading Intent: %s", err) + } + if err := d.Set("followup_intent_info", flattenDialogflowIntentFollowupIntentInfo(res["followupIntentInfo"], d, config)); err != nil { + return fmt.Errorf("Error reading Intent: %s", err) + } + + return nil +} + +func resourceDialogflowIntentUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + displayNameProp, err := expandDialogflowIntentDisplayName(d.Get("display_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("display_name"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, displayNameProp)) { + obj["displayName"] = displayNameProp + } + webhookStateProp, err := expandDialogflowIntentWebhookState(d.Get("webhook_state"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("webhook_state"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, webhookStateProp)) { + obj["webhookState"] = webhookStateProp + } + priorityProp, err := expandDialogflowIntentPriority(d.Get("priority"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("priority"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, priorityProp)) { + obj["priority"] = priorityProp + } + isFallbackProp, err := expandDialogflowIntentIsFallback(d.Get("is_fallback"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("is_fallback"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, isFallbackProp)) { + obj["isFallback"] = isFallbackProp + } + mlDisabledProp, err := expandDialogflowIntentMlDisabled(d.Get("ml_disabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("ml_disabled"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, mlDisabledProp)) { + obj["mlDisabled"] = mlDisabledProp + } + inputContextNamesProp, err := expandDialogflowIntentInputContextNames(d.Get("input_context_names"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("input_context_names"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, inputContextNamesProp)) { + obj["inputContextNames"] = inputContextNamesProp + } + eventsProp, err := expandDialogflowIntentEvents(d.Get("events"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("events"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, eventsProp)) { + obj["events"] = eventsProp + } + actionProp, err := expandDialogflowIntentAction(d.Get("action"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("action"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, actionProp)) { + obj["action"] = actionProp + } + resetContextsProp, err := expandDialogflowIntentResetContexts(d.Get("reset_contexts"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("reset_contexts"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, resetContextsProp)) { + obj["resetContexts"] = resetContextsProp + } + defaultResponsePlatformsProp, err := expandDialogflowIntentDefaultResponsePlatforms(d.Get("default_response_platforms"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("default_response_platforms"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, defaultResponsePlatformsProp)) { + obj["defaultResponsePlatforms"] = defaultResponsePlatformsProp + } + + url, err := replaceVars(d, config, "{{DialogflowBasePath}}{{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Updating Intent %q: %#v", d.Id(), obj) + _, err = sendRequestWithTimeout(config, "PATCH", project, url, obj, d.Timeout(schema.TimeoutUpdate)) + + if err != nil { + return fmt.Errorf("Error updating Intent %q: %s", d.Id(), err) + } + + return resourceDialogflowIntentRead(d, meta) +} + +func resourceDialogflowIntentDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + + project, err := getProject(d, config) + if err != nil { + return err + } + + url, err := replaceVars(d, config, "{{DialogflowBasePath}}{{name}}") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting Intent %q", d.Id()) + + res, err := sendRequestWithTimeout(config, "DELETE", project, url, obj, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return handleNotFoundError(err, d, "Intent") + } + + log.Printf("[DEBUG] Finished deleting Intent %q: %#v", d.Id(), res) + return nil +} + +func resourceDialogflowIntentImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + + config := meta.(*Config) + + // current import_formats can't import fields with forward slashes in their value + if err := parseImportId([]string{"(?P.+)"}, d, config); err != nil { + return nil, err + } + + stringParts := strings.Split(d.Get("name").(string), "/") + if len(stringParts) < 2 { + return nil, fmt.Errorf( + "Could not split project from name: %s", + d.Get("name"), + ) + } + + d.Set("project", stringParts[1]) + return []*schema.ResourceData{d}, nil +} + +func flattenDialogflowIntentName(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowIntentDisplayName(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowIntentWebhookState(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowIntentPriority(v interface{}, d *schema.ResourceData, config *Config) interface{} { + // Handles the string fixed64 format + if strVal, ok := v.(string); ok { + if intVal, err := strconv.ParseInt(strVal, 10, 64); err == nil { + return intVal + } + } + + // number values are represented as float64 + if floatVal, ok := v.(float64); ok { + intVal := int(floatVal) + return intVal + } + + return v // let terraform core handle it otherwise +} + +func flattenDialogflowIntentIsFallback(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowIntentMlDisabled(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowIntentInputContextNames(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowIntentEvents(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowIntentAction(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowIntentResetContexts(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowIntentDefaultResponsePlatforms(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowIntentRootFollowupIntentName(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowIntentParentFollowupIntentName(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowIntentFollowupIntentInfo(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return v + } + l := v.([]interface{}) + transformed := make([]interface{}, 0, len(l)) + for _, raw := range l { + original := raw.(map[string]interface{}) + if len(original) < 1 { + // Do not include empty json objects coming back from the api + continue + } + transformed = append(transformed, map[string]interface{}{ + "followup_intent_name": flattenDialogflowIntentFollowupIntentInfoFollowupIntentName(original["followupIntentName"], d, config), + "parent_followup_intent_name": flattenDialogflowIntentFollowupIntentInfoParentFollowupIntentName(original["parentFollowupIntentName"], d, config), + }) + } + return transformed +} +func flattenDialogflowIntentFollowupIntentInfoFollowupIntentName(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowIntentFollowupIntentInfoParentFollowupIntentName(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func expandDialogflowIntentDisplayName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandDialogflowIntentWebhookState(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandDialogflowIntentPriority(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandDialogflowIntentIsFallback(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandDialogflowIntentMlDisabled(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandDialogflowIntentInputContextNames(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandDialogflowIntentEvents(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandDialogflowIntentAction(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandDialogflowIntentResetContexts(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandDialogflowIntentDefaultResponsePlatforms(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandDialogflowIntentParentFollowupIntentName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} diff --git a/google-beta/resource_dialogflow_intent_generated_test.go b/google-beta/resource_dialogflow_intent_generated_test.go new file mode 100644 index 0000000000..635a30167d --- /dev/null +++ b/google-beta/resource_dialogflow_intent_generated_test.go @@ -0,0 +1,123 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +// +// ---------------------------------------------------------------------------- +// +// This file is automatically generated by Magic Modules and manual +// changes will be clobbered when the file is regenerated. +// +// Please read more about how to change this file in +// .github/CONTRIBUTING.md. +// +// ---------------------------------------------------------------------------- + +package google + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func TestAccDialogflowIntent_dialogflowIntentFullExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "org_id": getTestOrgFromEnv(t), + "random_suffix": acctest.RandString(10), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckDialogflowIntentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDialogflowIntent_dialogflowIntentFullExample(context), + }, + { + ResourceName: "google_dialogflow_intent.full_intent", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccDialogflowIntent_dialogflowIntentFullExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_project" "agent_project" { + project_id = "tf-test-dialogflow-%{random_suffix}" + name = "tf-test-dialogflow-%{random_suffix}" + org_id = "%{org_id}" +} + +resource "google_project_service" "agent_project" { + project = google_project.agent_project.project_id + service = "dialogflow.googleapis.com" + disable_dependent_services = false +} + +resource "google_service_account" "dialogflow_service_account" { + account_id = "tf-test-dialogflow-%{random_suffix}" +} + +resource "google_project_iam_member" "agent_create" { + project = google_project_service.agent_project.project + role = "roles/dialogflow.admin" + member = "serviceAccount:${google_service_account.dialogflow_service_account.email}" +} + +resource "google_dialogflow_agent" "basic_agent" { + project = google_project.agent_project.project_id + display_name = "example_agent" + default_language_code = "en" + time_zone = "America/New_York" +} + +resource "google_dialogflow_intent" "full_intent" { + project = google_project.agent_project.project_id + depends_on = [google_dialogflow_agent.basic_agent] + display_name = "tf-test-full-intent%{random_suffix}" + webhook_state = "WEBHOOK_STATE_ENABLED" + priority = 1 + is_fallback = false + ml_disabled = true + action = "some_action" + reset_contexts = true + input_context_names = ["projects/${google_project.agent_project.project_id}/agent/sessions/-/contexts/some_id"] + events = ["some_event"] + default_response_platforms = ["FACEBOOK","SLACK"] +} +`, context) +} + +func testAccCheckDialogflowIntentDestroy(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_dialogflow_intent" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := testAccProvider.Meta().(*Config) + + url, err := replaceVarsForTest(config, rs, "{{DialogflowBasePath}}{{name}}") + if err != nil { + return err + } + + _, err = sendRequest(config, "GET", "", url, nil) + if err == nil { + return fmt.Errorf("DialogflowIntent still exists at %s", url) + } + } + + return nil +} diff --git a/google-beta/resource_dialogflow_intent_test.go b/google-beta/resource_dialogflow_intent_test.go new file mode 100644 index 0000000000..0caae0754b --- /dev/null +++ b/google-beta/resource_dialogflow_intent_test.go @@ -0,0 +1,207 @@ +package google + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" +) + +func TestAccDialogflowIntent_basic(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "org_id": getTestOrgFromEnv(t), + "billing_account": getTestBillingAccountFromEnv(t), + "random_suffix": acctest.RandString(10), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDialogflowIntent_basic(context), + }, + { + ResourceName: "google_dialogflow_intent.foobar", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccDialogflowIntent_update(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "org_id": getTestOrgFromEnv(t), + "billing_account": getTestBillingAccountFromEnv(t), + "random_suffix": acctest.RandString(10), + } + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDialogflowIntent_full1(context), + }, + { + ResourceName: "google_dialogflow_intent.foobar", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccDialogflowIntent_full2(context), + }, + { + ResourceName: "google_dialogflow_intent.foobar", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccDialogflowIntent_basic(context map[string]interface{}) string { + return Nprintf(` + resource "google_project" "agent_project" { + name = "tf-test-dialogflow-%{random_suffix}" + project_id = "tf-test-dialogflow-%{random_suffix}" + org_id = "%{org_id}" + billing_account = "%{billing_account}" + } + + resource "google_project_service" "agent_project" { + project = google_project.agent_project.project_id + service = "dialogflow.googleapis.com" + disable_dependent_services = false + } + + resource "google_service_account" "dialogflow_service_account" { + account_id = "tf-test-dialogflow-%{random_suffix}" + } + + resource "google_project_iam_member" "agent_create" { + project = google_project_service.agent_project.project + role = "roles/dialogflow.admin" + member = "serviceAccount:${google_service_account.dialogflow_service_account.email}" + } + + resource "google_dialogflow_agent" "agent" { + project = google_project.agent_project.project_id + display_name = "tf-test-agent-%{random_suffix}" + default_language_code = "en" + time_zone = "America/New_York" + depends_on = [google_project_iam_member.agent_create] + } + + resource "google_dialogflow_intent" "foobar" { + depends_on = [google_dialogflow_agent.agent] + project = google_project.agent_project.project_id + display_name = "tf-test-%{random_suffix}" + } + `, context) +} + +func testAccDialogflowIntent_full1(context map[string]interface{}) string { + return Nprintf(` + resource "google_project" "agent_project" { + name = "tf-test-dialogflow-%{random_suffix}" + project_id = "tf-test-dialogflow-%{random_suffix}" + org_id = "%{org_id}" + billing_account = "%{billing_account}" + } + + resource "google_project_service" "agent_project" { + project = google_project.agent_project.project_id + service = "dialogflow.googleapis.com" + disable_dependent_services = false + } + + resource "google_service_account" "dialogflow_service_account" { + account_id = "tf-test-dialogflow-%{random_suffix}" + } + + resource "google_project_iam_member" "agent_create" { + project = google_project_service.agent_project.project + role = "roles/dialogflow.admin" + member = "serviceAccount:${google_service_account.dialogflow_service_account.email}" + } + + resource "google_dialogflow_agent" "agent" { + project = google_project.agent_project.project_id + display_name = "tf-test-agent-%{random_suffix}" + default_language_code = "en" + time_zone = "America/New_York" + depends_on = [google_project_iam_member.agent_create] + } + + resource "google_dialogflow_intent" "foobar" { + depends_on = [google_dialogflow_agent.agent] + project = google_project.agent_project.project_id + display_name = "tf-test-intent-%{random_suffix}" + webhook_state = "WEBHOOK_STATE_ENABLED" + priority = 1 + is_fallback = false + ml_disabled = true + action = "some_action" + reset_contexts = true + input_context_names = ["projects/${google_project.agent_project.project_id}/agent/sessions/-/contexts/some_id"] + events = ["some_event"] + default_response_platforms = ["FACEBOOK","SLACK"] + } + `, context) +} + +func testAccDialogflowIntent_full2(context map[string]interface{}) string { + return Nprintf(` + resource "google_project" "agent_project" { + name = "tf-test-dialogflow-%{random_suffix}" + project_id = "tf-test-dialogflow-%{random_suffix}" + org_id = "%{org_id}" + billing_account = "%{billing_account}" + } + + resource "google_project_service" "agent_project" { + project = google_project.agent_project.project_id + service = "dialogflow.googleapis.com" + disable_dependent_services = false + } + + resource "google_service_account" "dialogflow_service_account" { + account_id = "tf-test-dialogflow-%{random_suffix}" + } + + resource "google_project_iam_member" "agent_create" { + project = google_project_service.agent_project.project + role = "roles/dialogflow.admin" + member = "serviceAccount:${google_service_account.dialogflow_service_account.email}" + } + + resource "google_dialogflow_agent" "agent" { + project = google_project.agent_project.project_id + display_name = "tf-test-agent-%{random_suffix}" + default_language_code = "en" + time_zone = "America/New_York" + depends_on = [google_project_iam_member.agent_create] + } + + resource "google_dialogflow_intent" "foobar" { + depends_on = [google_dialogflow_agent.agent] + project = google_project.agent_project.project_id + display_name = "tf-test-intent-%{random_suffix}2" + webhook_state = "WEBHOOK_STATE_ENABLED_FOR_SLOT_FILLING" + priority = 2 + is_fallback = false + ml_disabled = false + action = "some_other_action" + reset_contexts = false + input_context_names = ["projects/${google_project.agent_project.project_id}/agent/sessions/-/contexts/some_other_id"] + events = ["some_other_event"] + default_response_platforms = ["SKYPE"] + } + `, context) +} diff --git a/website/docs/r/dialogflow_intent.html.markdown b/website/docs/r/dialogflow_intent.html.markdown new file mode 100644 index 0000000000..ae1ebbe2a9 --- /dev/null +++ b/website/docs/r/dialogflow_intent.html.markdown @@ -0,0 +1,229 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file in +# .github/CONTRIBUTING.md. +# +# ---------------------------------------------------------------------------- +subcategory: "Dialogflow" +layout: "google" +page_title: "Google: google_dialogflow_intent" +sidebar_current: "docs-google-dialogflow-intent" +description: |- + Represents a Dialogflow intent. +--- + +# google\_dialogflow\_intent + +Represents a Dialogflow intent. Intents convert a number of user expressions or patterns into an action. An action +is an extraction of a user command or sentence semantics. + + +To get more information about Intent, see: + +* [API documentation](https://cloud.google.com/dialogflow/docs/reference/rest/v2/projects.agent.intents) +* How-to Guides + * [Official Documentation](https://cloud.google.com/dialogflow/docs/) + +## Example Usage - Dialogflow Intent Basic + + +```hcl +resource "google_dialogflow_agent" "basic_agent" { + display_name = "example_agent" + default_language_code = "en" + time_zone = "America/New_York" +} + +resource "google_dialogflow_intent" "basic_intent" { + depends_on = [google_dialogflow_agent.basic_agent] + display_name = "basic-intent" +} +``` + +## Example Usage - Dialogflow Intent Full + + +```hcl +resource "google_project" "agent_project" { + project_id = "tf-test-dialogflow-%{random_suffix}" + name = "tf-test-dialogflow-%{random_suffix}" + org_id = "123456789" +} + +resource "google_project_service" "agent_project" { + project = google_project.agent_project.project_id + service = "dialogflow.googleapis.com" + disable_dependent_services = false +} + +resource "google_service_account" "dialogflow_service_account" { + account_id = "tf-test-dialogflow-%{random_suffix}" +} + +resource "google_project_iam_member" "agent_create" { + project = google_project_service.agent_project.project + role = "roles/dialogflow.admin" + member = "serviceAccount:${google_service_account.dialogflow_service_account.email}" +} + +resource "google_dialogflow_agent" "basic_agent" { + project = google_project.agent_project.project_id + display_name = "example_agent" + default_language_code = "en" + time_zone = "America/New_York" +} + +resource "google_dialogflow_intent" "full_intent" { + project = google_project.agent_project.project_id + depends_on = [google_dialogflow_agent.basic_agent] + display_name = "full-intent" + webhook_state = "WEBHOOK_STATE_ENABLED" + priority = 1 + is_fallback = false + ml_disabled = true + action = "some_action" + reset_contexts = true + input_context_names = ["projects/${google_project.agent_project.project_id}/agent/sessions/-/contexts/some_id"] + events = ["some_event"] + default_response_platforms = ["FACEBOOK","SLACK"] +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `display_name` - + (Required) + The name of this intent to be displayed on the console. + + +- - - + + +* `webhook_state` - + (Optional) + Indicates whether webhooks are enabled for the intent. + * WEBHOOK_STATE_ENABLED: Webhook is enabled in the agent and in the intent. + * WEBHOOK_STATE_ENABLED_FOR_SLOT_FILLING: Webhook is enabled in the agent and in the intent. Also, each slot + filling prompt is forwarded to the webhook. + +* `priority` - + (Optional) + The priority of this intent. Higher numbers represent higher priorities. + - If the supplied value is unspecified or 0, the service translates the value to 500,000, which corresponds + to the Normal priority in the console. + - If the supplied value is negative, the intent is ignored in runtime detect intent requests. + +* `is_fallback` - + (Optional) + Indicates whether this is a fallback intent. + +* `ml_disabled` - + (Optional) + Indicates whether Machine Learning is disabled for the intent. + Note: If mlDisabled setting is set to true, then this intent is not taken into account during inference in ML + ONLY match mode. Also, auto-markup in the UI is turned off. + +* `input_context_names` - + (Optional) + The list of context names required for this intent to be triggered. + Format: projects//agent/sessions/-/contexts/. + +* `events` - + (Optional) + The collection of event names that trigger the intent. If the collection of input contexts is not empty, all of + the contexts must be present in the active user session for an event to trigger this intent. See the + [events reference](https://cloud.google.com/dialogflow/docs/events-overview) for more details. + +* `action` - + (Optional) + The name of the action associated with the intent. + Note: The action name must not contain whitespaces. + +* `reset_contexts` - + (Optional) + Indicates whether to delete all contexts in the current session when this intent is matched. + +* `default_response_platforms` - + (Optional) + The list of platforms for which the first responses will be copied from the messages in PLATFORM_UNSPECIFIED + (i.e. default platform). + +* `parent_followup_intent_name` - + (Optional) + The unique identifier of the parent intent in the chain of followup intents. + Format: projects//agent/intents/. + +* `project` - (Optional) The ID of the project in which the resource belongs. + If it is not provided, the provider project is used. + + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `id` - an identifier for the resource with format `{{name}}` + +* `name` - + The unique identifier of this intent. + Format: projects//agent/intents/. + +* `root_followup_intent_name` - + The unique identifier of the root intent in the chain of followup intents. It identifies the correct followup + intents chain for this intent. + Format: projects//agent/intents/. + +* `followup_intent_info` - + Information about all followup intents that have this intent as a direct or indirect parent. We populate this field + only in the output. Structure is documented below. + + +The `followup_intent_info` block contains: + +* `followup_intent_name` - + (Optional) + The unique identifier of the followup intent. + Format: projects//agent/intents/. + +* `parent_followup_intent_name` - + (Optional) + The unique identifier of the followup intent's parent. + Format: projects//agent/intents/. + +## Timeouts + +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - Default is 4 minutes. +- `update` - Default is 4 minutes. +- `delete` - Default is 4 minutes. + +## Import + +Intent can be imported using any of these accepted formats: + +``` +$ terraform import google_dialogflow_intent.default {{name}} +``` + +-> If you're importing a resource with beta features, make sure to include `-provider=google-beta` +as an argument so that Terraform uses the correct provider to import your resource. + +## User Project Overrides + +This resource supports [User Project Overrides](https://www.terraform.io/docs/providers/google/guides/provider_reference.html#user_project_override). diff --git a/website/google.erb b/website/google.erb index 118e3da0c7..50743390d4 100644 --- a/website/google.erb +++ b/website/google.erb @@ -979,6 +979,18 @@ + > + Google Dialogflow Resources + + + > Google DNS Resources