From 2c56d2a5bbf56ef3fc14fc7e747924db623364e7 Mon Sep 17 00:00:00 2001 From: Modular Magician Date: Wed, 4 Aug 2021 00:19:33 +0000 Subject: [PATCH] New Resource : `google_dialogflowcx_entity_type` (#4924) * Including API definition for EntityType * Including acc tests for EntityTypes * Adding example for Dialogflow entity type * Refactoring with suggestions made in PR for versions * Updated Entity Type tests * Fix space in tests Signed-off-by: Modular Magician --- .changelog/4924.txt | 3 + google/provider.go | 5 +- google/resource_dialogflow_cx_entity_type.go | 603 ++++++++++++++++++ ...ialogflow_cx_entity_type_generated_test.go | 117 ++++ .../resource_dialogflowcx_entity_type_test.go | 124 ++++ .../r/dialogflow_cx_entity_type.html.markdown | 184 ++++++ website/google.erb | 4 + 7 files changed, 1038 insertions(+), 2 deletions(-) create mode 100644 .changelog/4924.txt create mode 100644 google/resource_dialogflow_cx_entity_type.go create mode 100644 google/resource_dialogflow_cx_entity_type_generated_test.go create mode 100644 google/resource_dialogflowcx_entity_type_test.go create mode 100644 website/docs/r/dialogflow_cx_entity_type.html.markdown diff --git a/.changelog/4924.txt b/.changelog/4924.txt new file mode 100644 index 00000000000..017961d663c --- /dev/null +++ b/.changelog/4924.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +`google_dialogflow_cx_entity_type` +``` diff --git a/google/provider.go b/google/provider.go index b13fcc1432e..b036a4e2d70 100644 --- a/google/provider.go +++ b/google/provider.go @@ -791,9 +791,9 @@ func Provider() *schema.Provider { return provider } -// Generated resources: 210 +// Generated resources: 211 // Generated IAM resources: 90 -// Total generated resources: 300 +// Total generated resources: 301 func ResourceMap() map[string]*schema.Resource { resourceMap, _ := ResourceMapWithErrors() return resourceMap @@ -966,6 +966,7 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) { "google_dialogflow_cx_flow": resourceDialogflowCXFlow(), "google_dialogflow_cx_version": resourceDialogflowCXVersion(), "google_dialogflow_cx_page": resourceDialogflowCXPage(), + "google_dialogflow_cx_entity_type": resourceDialogflowCXEntityType(), "google_dns_managed_zone": resourceDNSManagedZone(), "google_dns_policy": resourceDNSPolicy(), "google_dns_record_set": resourceDNSResourceDnsRecordSet(), diff --git a/google/resource_dialogflow_cx_entity_type.go b/google/resource_dialogflow_cx_entity_type.go new file mode 100644 index 00000000000..a9de1a9dc3c --- /dev/null +++ b/google/resource_dialogflow_cx_entity_type.go @@ -0,0 +1,603 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// 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" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceDialogflowCXEntityType() *schema.Resource { + return &schema.Resource{ + Create: resourceDialogflowCXEntityTypeCreate, + Read: resourceDialogflowCXEntityTypeRead, + Update: resourceDialogflowCXEntityTypeUpdate, + Delete: resourceDialogflowCXEntityTypeDelete, + + Importer: &schema.ResourceImporter{ + State: resourceDialogflowCXEntityTypeImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(40 * time.Minute), + Update: schema.DefaultTimeout(40 * time.Minute), + Delete: schema.DefaultTimeout(4 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "display_name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(0, 64), + Description: `The human-readable name of the entity type, unique within the agent.`, + }, + "entities": { + Type: schema.TypeList, + Required: true, + Description: `The collection of entity entries associated with the entity type.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "synonyms": { + Type: schema.TypeList, + Optional: true, + Description: `A collection of value synonyms. For example, if the entity type is vegetable, and value is scallions, a synonym could be green onions. +For KIND_LIST entity types: This collection must contain exactly one synonym equal to value.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "value": { + Type: schema.TypeString, + Optional: true, + Description: `The primary value associated with this entity entry. For example, if the entity type is vegetable, the value could be scallions. +For KIND_MAP entity types: A canonical value to be used in place of synonyms. +For KIND_LIST entity types: A string that can contain references to other entity types (with or without aliases).`, + }, + }, + }, + }, + "kind": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"KIND_MAP", "KIND_LIST", "KIND_REGEXP"}, false), + Description: `Indicates whether the entity type can be automatically expanded. +* KIND_MAP: Map entity types allow mapping of a group of synonyms to a canonical value. +* KIND_LIST: List entity types contain a set of entries that do not map to canonical values. However, list entity types can contain references to other entity types (with or without aliases). +* KIND_REGEXP: Regexp entity types allow to specify regular expressions in entries values. Possible values: ["KIND_MAP", "KIND_LIST", "KIND_REGEXP"]`, + }, + "auto_expansion_mode": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"AUTO_EXPANSION_MODE_DEFAULT", "AUTO_EXPANSION_MODE_UNSPECIFIED", ""}, false), + Description: `Represents kinds of entities. +* AUTO_EXPANSION_MODE_UNSPECIFIED: Auto expansion disabled for the entity. +* AUTO_EXPANSION_MODE_DEFAULT: Allows an agent to recognize values that have not been explicitly listed in the entity. Possible values: ["AUTO_EXPANSION_MODE_DEFAULT", "AUTO_EXPANSION_MODE_UNSPECIFIED"]`, + }, + "enable_fuzzy_extraction": { + Type: schema.TypeBool, + Optional: true, + Description: `Enables fuzzy entity extraction during classification.`, + }, + "excluded_phrases": { + Type: schema.TypeList, + Optional: true, + Description: `Collection of exceptional words and phrases that shouldn't be matched. For example, if you have a size entity type with entry giant(an adjective), you might consider adding giants(a noun) as an exclusion. +If the kind of entity type is KIND_MAP, then the phrases specified by entities and excluded phrases should be mutually exclusive.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "value": { + Type: schema.TypeString, + Optional: true, + Description: `The word or phrase to be excluded.`, + }, + }, + }, + }, + "language_code": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: `The language of the following fields in entityType: +EntityType.entities.value +EntityType.entities.synonyms +EntityType.excluded_phrases.value +If not specified, the agent's default language is used. Many languages are supported. Note: languages must be enabled in the agent before they can be used.`, + }, + "parent": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: `The agent to create a entity type for. +Format: projects//locations//agents/.`, + }, + "redact": { + Type: schema.TypeBool, + Optional: true, + Description: `Indicates whether parameters of the entity type should be redacted in log. If redaction is enabled, page parameters and intent parameters referring to the entity type will be replaced by parameter name when logging.`, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: `The unique identifier of the entity type. +Format: projects//locations//agents//entityTypes/.`, + }, + }, + UseJSONNumber: true, + } +} + +func resourceDialogflowCXEntityTypeCreate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + obj := make(map[string]interface{}) + displayNameProp, err := expandDialogflowCXEntityTypeDisplayName(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 + } + kindProp, err := expandDialogflowCXEntityTypeKind(d.Get("kind"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("kind"); !isEmptyValue(reflect.ValueOf(kindProp)) && (ok || !reflect.DeepEqual(v, kindProp)) { + obj["kind"] = kindProp + } + autoExpansionModeProp, err := expandDialogflowCXEntityTypeAutoExpansionMode(d.Get("auto_expansion_mode"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("auto_expansion_mode"); !isEmptyValue(reflect.ValueOf(autoExpansionModeProp)) && (ok || !reflect.DeepEqual(v, autoExpansionModeProp)) { + obj["autoExpansionMode"] = autoExpansionModeProp + } + entitiesProp, err := expandDialogflowCXEntityTypeEntities(d.Get("entities"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("entities"); !isEmptyValue(reflect.ValueOf(entitiesProp)) && (ok || !reflect.DeepEqual(v, entitiesProp)) { + obj["entities"] = entitiesProp + } + excludedPhrasesProp, err := expandDialogflowCXEntityTypeExcludedPhrases(d.Get("excluded_phrases"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("excluded_phrases"); !isEmptyValue(reflect.ValueOf(excludedPhrasesProp)) && (ok || !reflect.DeepEqual(v, excludedPhrasesProp)) { + obj["excludedPhrases"] = excludedPhrasesProp + } + enableFuzzyExtractionProp, err := expandDialogflowCXEntityTypeEnableFuzzyExtraction(d.Get("enable_fuzzy_extraction"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enable_fuzzy_extraction"); !isEmptyValue(reflect.ValueOf(enableFuzzyExtractionProp)) && (ok || !reflect.DeepEqual(v, enableFuzzyExtractionProp)) { + obj["enableFuzzyExtraction"] = enableFuzzyExtractionProp + } + redactProp, err := expandDialogflowCXEntityTypeRedact(d.Get("redact"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("redact"); !isEmptyValue(reflect.ValueOf(redactProp)) && (ok || !reflect.DeepEqual(v, redactProp)) { + obj["redact"] = redactProp + } + + url, err := replaceVars(d, config, "{{DialogflowCXBasePath}}{{parent}}/entityTypes") + if err != nil { + return err + } + + log.Printf("[DEBUG] Creating new EntityType: %#v", obj) + billingProject := "" + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequestWithTimeout(config, "POST", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return fmt.Errorf("Error creating EntityType: %s", err) + } + if err := d.Set("name", flattenDialogflowCXEntityTypeName(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, "{{parent}}/entityTypes/{{name}}") + if err != nil { + return fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + log.Printf("[DEBUG] Finished creating EntityType %q: %#v", d.Id(), res) + + return resourceDialogflowCXEntityTypeRead(d, meta) +} + +func resourceDialogflowCXEntityTypeRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + url, err := replaceVars(d, config, "{{DialogflowCXBasePath}}{{parent}}/entityTypes/{{name}}") + if err != nil { + return err + } + + billingProject := "" + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequest(config, "GET", billingProject, url, userAgent, nil) + if err != nil { + return handleNotFoundError(err, d, fmt.Sprintf("DialogflowCXEntityType %q", d.Id())) + } + + if err := d.Set("name", flattenDialogflowCXEntityTypeName(res["name"], d, config)); err != nil { + return fmt.Errorf("Error reading EntityType: %s", err) + } + if err := d.Set("display_name", flattenDialogflowCXEntityTypeDisplayName(res["displayName"], d, config)); err != nil { + return fmt.Errorf("Error reading EntityType: %s", err) + } + if err := d.Set("kind", flattenDialogflowCXEntityTypeKind(res["kind"], d, config)); err != nil { + return fmt.Errorf("Error reading EntityType: %s", err) + } + if err := d.Set("auto_expansion_mode", flattenDialogflowCXEntityTypeAutoExpansionMode(res["autoExpansionMode"], d, config)); err != nil { + return fmt.Errorf("Error reading EntityType: %s", err) + } + if err := d.Set("entities", flattenDialogflowCXEntityTypeEntities(res["entities"], d, config)); err != nil { + return fmt.Errorf("Error reading EntityType: %s", err) + } + if err := d.Set("excluded_phrases", flattenDialogflowCXEntityTypeExcludedPhrases(res["excludedPhrases"], d, config)); err != nil { + return fmt.Errorf("Error reading EntityType: %s", err) + } + if err := d.Set("enable_fuzzy_extraction", flattenDialogflowCXEntityTypeEnableFuzzyExtraction(res["enableFuzzyExtraction"], d, config)); err != nil { + return fmt.Errorf("Error reading EntityType: %s", err) + } + if err := d.Set("redact", flattenDialogflowCXEntityTypeRedact(res["redact"], d, config)); err != nil { + return fmt.Errorf("Error reading EntityType: %s", err) + } + + return nil +} + +func resourceDialogflowCXEntityTypeUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + billingProject := "" + + obj := make(map[string]interface{}) + displayNameProp, err := expandDialogflowCXEntityTypeDisplayName(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 + } + kindProp, err := expandDialogflowCXEntityTypeKind(d.Get("kind"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("kind"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, kindProp)) { + obj["kind"] = kindProp + } + autoExpansionModeProp, err := expandDialogflowCXEntityTypeAutoExpansionMode(d.Get("auto_expansion_mode"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("auto_expansion_mode"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, autoExpansionModeProp)) { + obj["autoExpansionMode"] = autoExpansionModeProp + } + entitiesProp, err := expandDialogflowCXEntityTypeEntities(d.Get("entities"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("entities"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, entitiesProp)) { + obj["entities"] = entitiesProp + } + excludedPhrasesProp, err := expandDialogflowCXEntityTypeExcludedPhrases(d.Get("excluded_phrases"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("excluded_phrases"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, excludedPhrasesProp)) { + obj["excludedPhrases"] = excludedPhrasesProp + } + enableFuzzyExtractionProp, err := expandDialogflowCXEntityTypeEnableFuzzyExtraction(d.Get("enable_fuzzy_extraction"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("enable_fuzzy_extraction"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, enableFuzzyExtractionProp)) { + obj["enableFuzzyExtraction"] = enableFuzzyExtractionProp + } + redactProp, err := expandDialogflowCXEntityTypeRedact(d.Get("redact"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("redact"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, redactProp)) { + obj["redact"] = redactProp + } + + url, err := replaceVars(d, config, "{{DialogflowCXBasePath}}{{parent}}/entityTypes/{{name}}") + if err != nil { + return err + } + + log.Printf("[DEBUG] Updating EntityType %q: %#v", d.Id(), obj) + updateMask := []string{} + + if d.HasChange("display_name") { + updateMask = append(updateMask, "displayName") + } + + if d.HasChange("kind") { + updateMask = append(updateMask, "kind") + } + + if d.HasChange("auto_expansion_mode") { + updateMask = append(updateMask, "autoExpansionMode") + } + + if d.HasChange("entities") { + updateMask = append(updateMask, "entities") + } + + if d.HasChange("excluded_phrases") { + updateMask = append(updateMask, "excludedPhrases") + } + + if d.HasChange("enable_fuzzy_extraction") { + updateMask = append(updateMask, "enableFuzzyExtraction") + } + + if d.HasChange("redact") { + updateMask = append(updateMask, "redact") + } + // updateMask is a URL parameter but not present in the schema, so replaceVars + // won't set it + url, err = addQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) + if err != nil { + return err + } + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequestWithTimeout(config, "PATCH", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutUpdate)) + + if err != nil { + return fmt.Errorf("Error updating EntityType %q: %s", d.Id(), err) + } else { + log.Printf("[DEBUG] Finished updating EntityType %q: %#v", d.Id(), res) + } + + return resourceDialogflowCXEntityTypeRead(d, meta) +} + +func resourceDialogflowCXEntityTypeDelete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + billingProject := "" + + url, err := replaceVars(d, config, "{{DialogflowCXBasePath}}{{parent}}/entityTypes/{{name}}") + if err != nil { + return err + } + + var obj map[string]interface{} + log.Printf("[DEBUG] Deleting EntityType %q", d.Id()) + + // err == nil indicates that the billing_project value was found + if bp, err := getBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := sendRequestWithTimeout(config, "DELETE", billingProject, url, userAgent, obj, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return handleNotFoundError(err, d, "EntityType") + } + + log.Printf("[DEBUG] Finished deleting EntityType %q: %#v", d.Id(), res) + return nil +} + +func resourceDialogflowCXEntityTypeImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + + // current import_formats can't import fields with forward slashes in their value and parent contains slashes + if err := parseImportId([]string{ + "(?P.+)/entityTypes/(?P[^/]+)", + "(?P.+)/(?P[^/]+)", + }, d, config); err != nil { + return nil, err + } + + // Replace import id for the resource id + id, err := replaceVars(d, config, "{{parent}}/entityTypes/{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenDialogflowCXEntityTypeName(v interface{}, d *schema.ResourceData, config *Config) interface{} { + if v == nil { + return v + } + return NameFromSelfLinkStateFunc(v) +} + +func flattenDialogflowCXEntityTypeDisplayName(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowCXEntityTypeKind(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowCXEntityTypeAutoExpansionMode(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowCXEntityTypeEntities(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{}{ + "value": flattenDialogflowCXEntityTypeEntitiesValue(original["value"], d, config), + "synonyms": flattenDialogflowCXEntityTypeEntitiesSynonyms(original["synonyms"], d, config), + }) + } + return transformed +} +func flattenDialogflowCXEntityTypeEntitiesValue(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowCXEntityTypeEntitiesSynonyms(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowCXEntityTypeExcludedPhrases(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{}{ + "value": flattenDialogflowCXEntityTypeExcludedPhrasesValue(original["value"], d, config), + }) + } + return transformed +} +func flattenDialogflowCXEntityTypeExcludedPhrasesValue(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowCXEntityTypeEnableFuzzyExtraction(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func flattenDialogflowCXEntityTypeRedact(v interface{}, d *schema.ResourceData, config *Config) interface{} { + return v +} + +func expandDialogflowCXEntityTypeDisplayName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandDialogflowCXEntityTypeKind(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandDialogflowCXEntityTypeAutoExpansionMode(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandDialogflowCXEntityTypeEntities(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedValue, err := expandDialogflowCXEntityTypeEntitiesValue(original["value"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedValue); val.IsValid() && !isEmptyValue(val) { + transformed["value"] = transformedValue + } + + transformedSynonyms, err := expandDialogflowCXEntityTypeEntitiesSynonyms(original["synonyms"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedSynonyms); val.IsValid() && !isEmptyValue(val) { + transformed["synonyms"] = transformedSynonyms + } + + req = append(req, transformed) + } + return req, nil +} + +func expandDialogflowCXEntityTypeEntitiesValue(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandDialogflowCXEntityTypeEntitiesSynonyms(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandDialogflowCXEntityTypeExcludedPhrases(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + l := v.([]interface{}) + req := make([]interface{}, 0, len(l)) + for _, raw := range l { + if raw == nil { + continue + } + original := raw.(map[string]interface{}) + transformed := make(map[string]interface{}) + + transformedValue, err := expandDialogflowCXEntityTypeExcludedPhrasesValue(original["value"], d, config) + if err != nil { + return nil, err + } else if val := reflect.ValueOf(transformedValue); val.IsValid() && !isEmptyValue(val) { + transformed["value"] = transformedValue + } + + req = append(req, transformed) + } + return req, nil +} + +func expandDialogflowCXEntityTypeExcludedPhrasesValue(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandDialogflowCXEntityTypeEnableFuzzyExtraction(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandDialogflowCXEntityTypeRedact(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) { + return v, nil +} diff --git a/google/resource_dialogflow_cx_entity_type_generated_test.go b/google/resource_dialogflow_cx_entity_type_generated_test.go new file mode 100644 index 00000000000..4e8b18a837d --- /dev/null +++ b/google/resource_dialogflow_cx_entity_type_generated_test.go @@ -0,0 +1,117 @@ +// ---------------------------------------------------------------------------- +// +// *** AUTO GENERATED CODE *** Type: MMv1 *** +// +// ---------------------------------------------------------------------------- +// +// 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/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccDialogflowCXEntityType_dialogflowcxEntityTypeFullExample(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckDialogflowCXEntityTypeDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccDialogflowCXEntityType_dialogflowcxEntityTypeFullExample(context), + }, + { + ResourceName: "google_dialogflow_cx_entity_type.basic_entity_type", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"parent", "language_code"}, + }, + }, + }) +} + +func testAccDialogflowCXEntityType_dialogflowcxEntityTypeFullExample(context map[string]interface{}) string { + return Nprintf(` +resource "google_dialogflow_cx_agent" "agent" { + display_name = "tf-test-dialogflowcx-agent%{random_suffix}" + location = "global" + default_language_code = "en" + supported_language_codes = ["fr","de","es"] + time_zone = "America/New_York" + description = "Example description." + avatar_uri = "https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png" + enable_stackdriver_logging = true + enable_spell_correction = true + speech_to_text_settings { + enable_speech_adaptation = true + } +} + + +resource "google_dialogflow_cx_entity_type" "basic_entity_type" { + parent = google_dialogflow_cx_agent.agent.id + display_name = "MyEntity" + kind = "KIND_MAP" + entities { + value = "value1" + synonyms = ["synonym1","synonym2"] + } + entities { + value = "value2" + synonyms = ["synonym3","synonym4"] + } + enable_fuzzy_extraction = false +} +`, context) +} + +func testAccCheckDialogflowCXEntityTypeDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_dialogflow_cx_entity_type" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := googleProviderConfig(t) + + url, err := replaceVarsForTest(config, rs, "{{DialogflowCXBasePath}}{{parent}}/entityTypes/{{name}}") + if err != nil { + return err + } + + billingProject := "" + + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + _, err = sendRequest(config, "GET", billingProject, url, config.userAgent, nil) + if err == nil { + return fmt.Errorf("DialogflowCXEntityType still exists at %s", url) + } + } + + return nil + } +} diff --git a/google/resource_dialogflowcx_entity_type_test.go b/google/resource_dialogflowcx_entity_type_test.go new file mode 100644 index 00000000000..8bacdd86243 --- /dev/null +++ b/google/resource_dialogflowcx_entity_type_test.go @@ -0,0 +1,124 @@ +package google + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccDialogflowCXEntityType_update(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "org_id": getTestOrgFromEnv(t), + "billing_account": getTestBillingAccountFromEnv(t), + "random_suffix": randString(t, 10), + } + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDialogflowCXEntityType_basic(context), + }, + { + ResourceName: "google_dialogflow_cx_entity_type.my_entity", + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccDialogflowCXEntityType_full(context), + }, + { + ResourceName: "google_dialogflow_cx_entity_type.my_entity", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccDialogflowCXEntityType_basic(context map[string]interface{}) string { + return Nprintf(` + resource "google_service_account" "dialogflowcx_service_account" { + account_id = "tf-test-dialogflow-%{random_suffix}" + } + + resource "google_project_iam_member" "agent_create" { + role = "roles/dialogflow.admin" + member = "serviceAccount:${google_service_account.dialogflowcx_service_account.email}" + } + + resource "google_dialogflow_cx_agent" "agent_entity" { + display_name = "tf-test-%{random_suffix}" + location = "global" + default_language_code = "en" + supported_language_codes = ["fr","de","es"] + time_zone = "America/New_York" + description = "Description 1." + avatar_uri = "https://storage.cloud.google.com/dialogflow-test-host-image/cloud-logo.png" + depends_on = [google_project_iam_member.agent_create] + } + + resource "google_dialogflow_cx_entity_type" "my_entity" { + parent = google_dialogflow_cx_agent.agent_entity.id + display_name = "MyEntity" + kind = "KIND_MAP" + entities { + value = "value1" + synonyms = ["synonym1","synonym2"] + } + entities { + value = "value2" + synonyms = ["synonym3","synonym4"] + } + enable_fuzzy_extraction = false + } + `, context) +} + +func testAccDialogflowCXEntityType_full(context map[string]interface{}) string { + return Nprintf(` + resource "google_service_account" "dialogflowcx_service_account" { + account_id = "tf-test-dialogflow-%{random_suffix}" + } + + resource "google_project_iam_member" "agent_create" { + role = "roles/dialogflow.admin" + member = "serviceAccount:${google_service_account.dialogflowcx_service_account.email}" + } + + resource "google_dialogflow_cx_agent" "agent_entity" { + display_name = "tf-test-%{random_suffix}" + location = "global" + default_language_code = "en" + supported_language_codes = ["fr","de","es"] + time_zone = "America/New_York" + description = "Description 1." + avatar_uri = "https://storage.cloud.google.com/dialogflow-test-host-image/cloud-logo.png" + depends_on = [google_project_iam_member.agent_create] + } + + resource "google_dialogflow_cx_entity_type" "my_entity" { + parent = google_dialogflow_cx_agent.agent_entity.id + display_name = "MyEntity" + kind = "KIND_MAP" + entities { + value = "value1" + synonyms = ["synonym1","synonym2","synonym11","synonym22"] + } + entities { + value = "value2" + synonyms = ["synonym3","synonym4"] + } + enable_fuzzy_extraction = false + redact = true + auto_expansion_mode = "AUTO_EXPANSION_MODE_DEFAULT" + excluded_phrases { + value = "excluded1" + } + + } + `, context) +} diff --git a/website/docs/r/dialogflow_cx_entity_type.html.markdown b/website/docs/r/dialogflow_cx_entity_type.html.markdown new file mode 100644 index 00000000000..08990ec9733 --- /dev/null +++ b/website/docs/r/dialogflow_cx_entity_type.html.markdown @@ -0,0 +1,184 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** Type: MMv1 *** +# +# ---------------------------------------------------------------------------- +# +# 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 CX" +layout: "google" +page_title: "Google: google_dialogflow_cx_entity_type" +sidebar_current: "docs-google-dialogflow-cx-entity-type" +description: |- + Entities are extracted from user input and represent parameters that are meaningful to your application. +--- + +# google\_dialogflow\_cx\_entity\_type + +Entities are extracted from user input and represent parameters that are meaningful to your application. +For example, a date range, a proper name such as a geographic location or landmark, and so on. Entities represent actionable data for your application. + + +To get more information about EntityType, see: + +* [API documentation](https://cloud.google.com/dialogflow/cx/docs/reference/rest/v3/projects.locations.agents.entityTypes) +* How-to Guides + * [Official Documentation](https://cloud.google.com/dialogflow/cx/docs) + + +## Example Usage - Dialogflowcx Entity Type Full + + +```hcl +resource "google_dialogflow_cx_agent" "agent" { + display_name = "dialogflowcx-agent" + location = "global" + default_language_code = "en" + supported_language_codes = ["fr","de","es"] + time_zone = "America/New_York" + description = "Example description." + avatar_uri = "https://cloud.google.com/_static/images/cloud/icons/favicons/onecloud/super_cloud.png" + enable_stackdriver_logging = true + enable_spell_correction = true + speech_to_text_settings { + enable_speech_adaptation = true + } +} + + +resource "google_dialogflow_cx_entity_type" "basic_entity_type" { + parent = google_dialogflow_cx_agent.agent.id + display_name = "MyEntity" + kind = "KIND_MAP" + entities { + value = "value1" + synonyms = ["synonym1","synonym2"] + } + entities { + value = "value2" + synonyms = ["synonym3","synonym4"] + } + enable_fuzzy_extraction = false +} +``` + +## Argument Reference + +The following arguments are supported: + + +* `display_name` - + (Required) + The human-readable name of the entity type, unique within the agent. + +* `kind` - + (Required) + Indicates whether the entity type can be automatically expanded. + * KIND_MAP: Map entity types allow mapping of a group of synonyms to a canonical value. + * KIND_LIST: List entity types contain a set of entries that do not map to canonical values. However, list entity types can contain references to other entity types (with or without aliases). + * KIND_REGEXP: Regexp entity types allow to specify regular expressions in entries values. + Possible values are `KIND_MAP`, `KIND_LIST`, and `KIND_REGEXP`. + +* `entities` - + (Required) + The collection of entity entries associated with the entity type. + Structure is documented below. + + +The `entities` block supports: + +* `value` - + (Optional) + The primary value associated with this entity entry. For example, if the entity type is vegetable, the value could be scallions. + For KIND_MAP entity types: A canonical value to be used in place of synonyms. + For KIND_LIST entity types: A string that can contain references to other entity types (with or without aliases). + +* `synonyms` - + (Optional) + A collection of value synonyms. For example, if the entity type is vegetable, and value is scallions, a synonym could be green onions. + For KIND_LIST entity types: This collection must contain exactly one synonym equal to value. + +- - - + + +* `auto_expansion_mode` - + (Optional) + Represents kinds of entities. + * AUTO_EXPANSION_MODE_UNSPECIFIED: Auto expansion disabled for the entity. + * AUTO_EXPANSION_MODE_DEFAULT: Allows an agent to recognize values that have not been explicitly listed in the entity. + Possible values are `AUTO_EXPANSION_MODE_DEFAULT` and `AUTO_EXPANSION_MODE_UNSPECIFIED`. + +* `excluded_phrases` - + (Optional) + Collection of exceptional words and phrases that shouldn't be matched. For example, if you have a size entity type with entry giant(an adjective), you might consider adding giants(a noun) as an exclusion. + If the kind of entity type is KIND_MAP, then the phrases specified by entities and excluded phrases should be mutually exclusive. + Structure is documented below. + +* `enable_fuzzy_extraction` - + (Optional) + Enables fuzzy entity extraction during classification. + +* `redact` - + (Optional) + Indicates whether parameters of the entity type should be redacted in log. If redaction is enabled, page parameters and intent parameters referring to the entity type will be replaced by parameter name when logging. + +* `parent` - + (Optional) + The agent to create a entity type for. + Format: projects//locations//agents/. + +* `language_code` - + (Optional) + The language of the following fields in entityType: + EntityType.entities.value + EntityType.entities.synonyms + EntityType.excluded_phrases.value + If not specified, the agent's default language is used. Many languages are supported. Note: languages must be enabled in the agent before they can be used. + + +The `excluded_phrases` block supports: + +* `value` - + (Optional) + The word or phrase to be excluded. + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `id` - an identifier for the resource with format `{{parent}}/entityTypes/{{name}}` + +* `name` - + The unique identifier of the entity type. + Format: projects//locations//agents//entityTypes/. + + +## Timeouts + +This resource provides the following +[Timeouts](/docs/configuration/resources.html#timeouts) configuration options: + +- `create` - Default is 40 minutes. +- `update` - Default is 40 minutes. +- `delete` - Default is 4 minutes. + +## Import + + +EntityType can be imported using any of these accepted formats: + +``` +$ terraform import google_dialogflow_cx_entity_type.default {{parent}}/entityTypes/{{name}} +$ terraform import google_dialogflow_cx_entity_type.default {{parent}}/{{name}} +``` diff --git a/website/google.erb b/website/google.erb index 3ea27275ee5..dd793b759fe 100644 --- a/website/google.erb +++ b/website/google.erb @@ -2292,6 +2292,10 @@ google_dialogflow_cx_agent +
  • + google_dialogflow_cx_entity_type +
  • +
  • google_dialogflow_cx_flow