diff --git a/.changelog/15296.txt b/.changelog/15296.txt new file mode 100644 index 00000000000..97c9edeeec7 --- /dev/null +++ b/.changelog/15296.txt @@ -0,0 +1,15 @@ +```release-note:enhancement +discoveryengine: added `connector_modes`, `sync_mode`, `incremental_refresh_interval`, `auto_run_disabled`, and `incremental_sync_disabled` fields to `google_discovery_engine_data_connector` resource +``` + +```release-note:enhancement +discoveryengine: added `kms_key_name` field to `google_discovery_engine_search_engine` resource +``` + +```release-note:bug +discoveryengine: fixed bug where it wasn't possible to specify values for `knowledgeBaseSysId` or `catalogSysId` in `google_discovery_engine_data_connector.entities.params`. +``` + +```release-note:breaking-change +discoveryengine: changed type of `google_discovery_engine_data_connector.entities.params`. Previously, it was a map of string keys to string values; now, it must be a [JSON-encoded](https://developer.hashicorp.com/terraform/language/functions/jsonencode) string containing an object. This change is being made in a minor release because the field wasn't usable as intended – specifically, all current valid uses require mapping strings to _lists_ of strings. +``` \ No newline at end of file diff --git a/google/services/discoveryengine/resource_discovery_engine_data_connector.go b/google/services/discoveryengine/resource_discovery_engine_data_connector.go index d102744bf85..cd4857a92c9 100644 --- a/google/services/discoveryengine/resource_discovery_engine_data_connector.go +++ b/google/services/discoveryengine/resource_discovery_engine_data_connector.go @@ -20,6 +20,8 @@ package discoveryengine import ( + "context" + "encoding/json" "fmt" "log" "net/http" @@ -29,11 +31,17 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/hashicorp/terraform-provider-google/google/tpgresource" transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" ) +func DataConnectorEntitiesParamsDiffSuppress(k, old, new string, d *schema.ResourceData) bool { + return (old == "" && new == "{}") || (old == "{}" && new == "") +} + func ResourceDiscoveryEngineDataConnector() *schema.Resource { return &schema.Resource{ Create: resourceDiscoveryEngineDataConnectorCreate, @@ -51,6 +59,15 @@ func ResourceDiscoveryEngineDataConnector() *schema.Resource { Delete: schema.DefaultTimeout(20 * time.Minute), }, + SchemaVersion: 1, + + StateUpgraders: []schema.StateUpgrader{ + { + Type: resourceDiscoveryEngineDataConnectorResourceV0().CoreConfigSchema().ImpliedType(), + Upgrade: ResourceDiscoveryEngineDataConnectorUpgradeV0, + Version: 0, + }, + }, CustomizeDiff: customdiff.All( tpgresource.DefaultProviderProject, ), @@ -99,6 +116,21 @@ minimum is 30 minutes and maximum is 7 days. When the refresh interval is set to the same value as the incremental refresh interval, incremental sync will be disabled.`, }, + "auto_run_disabled": { + Type: schema.TypeBool, + Optional: true, + Description: `Indicates whether full syncs are paused for this connector`, + }, + "connector_modes": { + Type: schema.TypeList, + Optional: true, + Description: `The modes enabled for this connector. The possible value can be: +'DATA_INGESTION', 'ACTIONS', 'FEDERATED' +'EUA', 'FEDERATED_AND_EUA'.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, "entities": { Type: schema.TypeList, Optional: true, @@ -128,10 +160,12 @@ Value: The key property to map a field to, such as 'title', and Elem: &schema.Schema{Type: schema.TypeString}, }, "params": { - Type: schema.TypeMap, - Optional: true, - Description: `The parameters for the entity to facilitate data ingestion.`, - Elem: &schema.Schema{Type: schema.TypeString}, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringIsJSON, + DiffSuppressFunc: DataConnectorEntitiesParamsDiffSuppress, + StateFunc: func(v interface{}) string { s, _ := structure.NormalizeJsonString(v); return s }, + Description: `The parameters for the entity to facilitate data ingestion.`, }, "data_store": { Type: schema.TypeString, @@ -145,6 +179,21 @@ method, a DataStore is automatically created for each source entity.`, }, }, }, + "incremental_refresh_interval": { + Type: schema.TypeString, + Optional: true, + Description: `The refresh interval specifically for incremental data syncs. If unset, +incremental syncs will use the default from env, set to 3hrs. +The minimum is 30 minutes and maximum is 7 days. Applicable to only 3P +connectors. When the refresh interval is +set to the same value as the incremental refresh interval, incremental +sync will be disabled.`, + }, + "incremental_sync_disabled": { + Type: schema.TypeBool, + Optional: true, + Description: `Indicates whether incremental syncs are paused for this connector.`, + }, "json_params": { Type: schema.TypeString, Optional: true, @@ -174,6 +223,12 @@ this connector will be protected by the KMS key.`, ForceNew: true, Description: `Whether customer has enabled static IP addresses for this connector.`, }, + "sync_mode": { + Type: schema.TypeString, + Optional: true, + Description: `The data synchronization mode supported by the data connector. The possible value can be: +'PERIODIC', 'STREAMING'.`, + }, "action_state": { Type: schema.TypeString, Computed: true, @@ -341,6 +396,36 @@ func resourceDiscoveryEngineDataConnectorCreate(d *schema.ResourceData, meta int } else if v, ok := d.GetOkExists("static_ip_enabled"); !tpgresource.IsEmptyValue(reflect.ValueOf(staticIpEnabledProp)) && (ok || !reflect.DeepEqual(v, staticIpEnabledProp)) { obj["staticIpEnabled"] = staticIpEnabledProp } + connectorModesProp, err := expandDiscoveryEngineDataConnectorConnectorModes(d.Get("connector_modes"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("connector_modes"); !tpgresource.IsEmptyValue(reflect.ValueOf(connectorModesProp)) && (ok || !reflect.DeepEqual(v, connectorModesProp)) { + obj["connectorModes"] = connectorModesProp + } + syncModeProp, err := expandDiscoveryEngineDataConnectorSyncMode(d.Get("sync_mode"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("sync_mode"); !tpgresource.IsEmptyValue(reflect.ValueOf(syncModeProp)) && (ok || !reflect.DeepEqual(v, syncModeProp)) { + obj["syncMode"] = syncModeProp + } + incrementalRefreshIntervalProp, err := expandDiscoveryEngineDataConnectorIncrementalRefreshInterval(d.Get("incremental_refresh_interval"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("incremental_refresh_interval"); !tpgresource.IsEmptyValue(reflect.ValueOf(incrementalRefreshIntervalProp)) && (ok || !reflect.DeepEqual(v, incrementalRefreshIntervalProp)) { + obj["incrementalRefreshInterval"] = incrementalRefreshIntervalProp + } + autoRunDisabledProp, err := expandDiscoveryEngineDataConnectorAutoRunDisabled(d.Get("auto_run_disabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("auto_run_disabled"); !tpgresource.IsEmptyValue(reflect.ValueOf(autoRunDisabledProp)) && (ok || !reflect.DeepEqual(v, autoRunDisabledProp)) { + obj["autoRunDisabled"] = autoRunDisabledProp + } + incrementalSyncDisabledProp, err := expandDiscoveryEngineDataConnectorIncrementalSyncDisabled(d.Get("incremental_sync_disabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("incremental_sync_disabled"); !tpgresource.IsEmptyValue(reflect.ValueOf(incrementalSyncDisabledProp)) && (ok || !reflect.DeepEqual(v, incrementalSyncDisabledProp)) { + obj["incrementalSyncDisabled"] = incrementalSyncDisabledProp + } url, err := tpgresource.ReplaceVars(d, config, "{{DiscoveryEngineBasePath}}projects/{{project}}/locations/{{location}}:setUpDataConnectorV2?collectionId={{collection_id}}&collectionDisplayName={{collection_display_name}}") if err != nil { @@ -494,6 +579,12 @@ func resourceDiscoveryEngineDataConnectorRead(d *schema.ResourceData, meta inter if err := d.Set("realtime_state", flattenDiscoveryEngineDataConnectorRealtimeState(res["realtimeState"], d, config)); err != nil { return fmt.Errorf("Error reading DataConnector: %s", err) } + if err := d.Set("connector_modes", flattenDiscoveryEngineDataConnectorConnectorModes(res["connectorModes"], d, config)); err != nil { + return fmt.Errorf("Error reading DataConnector: %s", err) + } + if err := d.Set("incremental_refresh_interval", flattenDiscoveryEngineDataConnectorIncrementalRefreshInterval(res["incrementalRefreshInterval"], d, config)); err != nil { + return fmt.Errorf("Error reading DataConnector: %s", err) + } return nil } @@ -532,6 +623,36 @@ func resourceDiscoveryEngineDataConnectorUpdate(d *schema.ResourceData, meta int } else if v, ok := d.GetOkExists("refresh_interval"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, refreshIntervalProp)) { obj["refreshInterval"] = refreshIntervalProp } + connectorModesProp, err := expandDiscoveryEngineDataConnectorConnectorModes(d.Get("connector_modes"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("connector_modes"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, connectorModesProp)) { + obj["connectorModes"] = connectorModesProp + } + syncModeProp, err := expandDiscoveryEngineDataConnectorSyncMode(d.Get("sync_mode"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("sync_mode"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, syncModeProp)) { + obj["syncMode"] = syncModeProp + } + incrementalRefreshIntervalProp, err := expandDiscoveryEngineDataConnectorIncrementalRefreshInterval(d.Get("incremental_refresh_interval"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("incremental_refresh_interval"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, incrementalRefreshIntervalProp)) { + obj["incrementalRefreshInterval"] = incrementalRefreshIntervalProp + } + autoRunDisabledProp, err := expandDiscoveryEngineDataConnectorAutoRunDisabled(d.Get("auto_run_disabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("auto_run_disabled"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, autoRunDisabledProp)) { + obj["autoRunDisabled"] = autoRunDisabledProp + } + incrementalSyncDisabledProp, err := expandDiscoveryEngineDataConnectorIncrementalSyncDisabled(d.Get("incremental_sync_disabled"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("incremental_sync_disabled"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, incrementalSyncDisabledProp)) { + obj["incrementalSyncDisabled"] = incrementalSyncDisabledProp + } url, err := tpgresource.ReplaceVars(d, config, "{{DiscoveryEngineBasePath}}projects/{{project}}/locations/{{location}}/collections/{{collection_id}}/dataConnector") if err != nil { @@ -553,6 +674,26 @@ func resourceDiscoveryEngineDataConnectorUpdate(d *schema.ResourceData, meta int if d.HasChange("refresh_interval") { updateMask = append(updateMask, "refreshInterval") } + + if d.HasChange("connector_modes") { + updateMask = append(updateMask, "connectorModes") + } + + if d.HasChange("sync_mode") { + updateMask = append(updateMask, "syncMode") + } + + if d.HasChange("incremental_refresh_interval") { + updateMask = append(updateMask, "incrementalRefreshInterval") + } + + if d.HasChange("auto_run_disabled") { + updateMask = append(updateMask, "autoRunDisabled") + } + + if d.HasChange("incremental_sync_disabled") { + updateMask = append(updateMask, "incrementalSyncDisabled") + } // updateMask is a URL parameter but not present in the schema, so ReplaceVars // won't set it url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) @@ -715,7 +856,15 @@ func flattenDiscoveryEngineDataConnectorEntitiesDataStore(v interface{}, d *sche } func flattenDiscoveryEngineDataConnectorEntitiesParams(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { - return v + if v == nil { + return nil + } + b, err := json.Marshal(v) + if err != nil { + // TODO: return error once https://github.com/GoogleCloudPlatform/magic-modules/issues/3257 is fixed. + log.Printf("[ERROR] failed to marshal schema to JSON: %v", err) + } + return string(b) } func flattenDiscoveryEngineDataConnectorCreateTime(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { @@ -806,6 +955,14 @@ func flattenDiscoveryEngineDataConnectorRealtimeState(v interface{}, d *schema.R return v } +func flattenDiscoveryEngineDataConnectorConnectorModes(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenDiscoveryEngineDataConnectorIncrementalRefreshInterval(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + func expandDiscoveryEngineDataConnectorDataSource(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } @@ -894,13 +1051,14 @@ func expandDiscoveryEngineDataConnectorEntitiesDataStore(v interface{}, d tpgres return v, nil } -func expandDiscoveryEngineDataConnectorEntitiesParams(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (map[string]string, error) { - if v == nil { - return map[string]string{}, nil +func expandDiscoveryEngineDataConnectorEntitiesParams(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + b := []byte(v.(string)) + if len(b) == 0 { + return nil, nil } - m := make(map[string]string) - for k, val := range v.(map[string]interface{}) { - m[k] = val.(string) + m := make(map[string]interface{}) + if err := json.Unmarshal(b, &m); err != nil { + return nil, err } return m, nil } @@ -912,3 +1070,323 @@ func expandDiscoveryEngineDataConnectorKmsKeyName(v interface{}, d tpgresource.T func expandDiscoveryEngineDataConnectorStaticIpEnabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { return v, nil } + +func expandDiscoveryEngineDataConnectorConnectorModes(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandDiscoveryEngineDataConnectorSyncMode(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandDiscoveryEngineDataConnectorIncrementalRefreshInterval(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandDiscoveryEngineDataConnectorAutoRunDisabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func expandDiscoveryEngineDataConnectorIncrementalSyncDisabled(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + +func ResourceDiscoveryEngineDataConnectorUpgradeV0(_ context.Context, rawState map[string]interface{}, meta interface{}) (map[string]interface{}, error) { + log.Printf("[DEBUG] Attributes before migration: %#v", rawState) + // Version 0 had entities.params as KeyValuePairs; Version 1 makes it a json string. + entitiesRaw, ok := rawState["entities"] + if !ok { + return rawState, nil + } + entities, ok := entitiesRaw.([]interface{}) + for _, entity := range entities { + entityMap, ok := entity.(map[string]interface{}) + if !ok { + continue + } + if p, ok := entityMap["params"]; ok && p != nil { + p, err := json.Marshal(entityMap["params"]) + if err != nil { + p = []byte(fmt.Sprintf("%v", entityMap["params"])) + } + entityMap["params"] = string(p) + } + } + log.Printf("[DEBUG] Attributes after migration: %#v", rawState) + return rawState, nil +} + +func resourceDiscoveryEngineDataConnectorResourceV0() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "collection_display_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The display name of the Collection. +Should be human readable, used to display collections in the Console +Dashboard. UTF-8 encoded string with limit of 1024 characters.`, + }, + "collection_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The ID to use for the Collection, which will become the final component +of the Collection's resource name. A new Collection is created as +part of the DataConnector setup. DataConnector is a singleton +resource under Collection, managing all DataStores of the Collection. +This field must conform to [RFC-1034](https://tools.ietf.org/html/rfc1034) +standard with a length limit of 63 characters. Otherwise, an +INVALID_ARGUMENT error is returned.`, + }, + "data_source": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The name of the data source. +Supported values: 'salesforce', 'jira', 'confluence', 'bigquery'.`, + }, + "location": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The geographic location where the data store should reside. The value can +only be one of "global", "us" and "eu".`, + }, + "refresh_interval": { + Type: schema.TypeString, + Required: true, + Description: `The refresh interval for data sync. If duration is set to 0, the data will +be synced in real time. The streaming feature is not supported yet. The +minimum is 30 minutes and maximum is 7 days. When the refresh interval is +set to the same value as the incremental refresh interval, incremental +sync will be disabled.`, + }, + "auto_run_disabled": { + Type: schema.TypeBool, + Optional: true, + Description: `Indicates whether full syncs are paused for this connector`, + }, + "connector_modes": { + Type: schema.TypeList, + Optional: true, + Description: `The modes enabled for this connector. The possible value can be: +'DATA_INGESTION', 'ACTIONS', 'FEDERATED' +'EUA', 'FEDERATED_AND_EUA'.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "entities": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Description: `List of entities from the connected data source to ingest.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "entity_name": { + Type: schema.TypeString, + Optional: true, + Description: `The name of the entity. Supported values by data source: +* Salesforce: 'Lead', 'Opportunity', 'Contact', 'Account', 'Case', 'Contract', 'Campaign' +* Jira: project, issue, attachment, comment, worklog +* Confluence: 'Content', 'Space'`, + }, + "key_property_mappings": { + Type: schema.TypeMap, + Optional: true, + Description: `Attributes for indexing. +Key: Field name. +Value: The key property to map a field to, such as 'title', and +'description'. Supported key properties: +* 'title': The title for data record. This would be displayed on search + results. +* 'description': The description for data record. This would be displayed + on search results.`, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "params": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringIsJSON, + StateFunc: func(v interface{}) string { s, _ := structure.NormalizeJsonString(v); return s }, + Description: `The parameters for the entity to facilitate data ingestion.`, + }, + "data_store": { + Type: schema.TypeString, + Computed: true, + Description: `The full resource name of the associated data store for the source +entity. +Format: 'projects/*/locations/*/collections/*/dataStores/*'. +When the connector is initialized by the DataConnectorService.SetUpDataConnector +method, a DataStore is automatically created for each source entity.`, + }, + }, + }, + }, + "incremental_refresh_interval": { + Type: schema.TypeString, + Optional: true, + Description: `The refresh interval specifically for incremental data syncs. If unset, +incremental syncs will use the default from env, set to 3hrs. +The minimum is 30 minutes and maximum is 7 days. Applicable to only 3P +connectors. When the refresh interval is +set to the same value as the incremental refresh interval, incremental +sync will be disabled.`, + }, + "incremental_sync_disabled": { + Type: schema.TypeBool, + Optional: true, + Description: `Indicates whether incremental syncs are paused for this connector.`, + }, + "json_params": { + Type: schema.TypeString, + Optional: true, + Description: `Params needed to access the source in the format of json string.`, + ExactlyOneOf: []string{"params", "json_params"}, + }, + "kms_key_name": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: `The KMS key to be used to protect the DataStores managed by this connector. +Must be set for requests that need to comply with CMEK Org Policy +protections. +If this field is set and processed successfully, the DataStores created by +this connector will be protected by the KMS key.`, + }, + "params": { + Type: schema.TypeMap, + Optional: true, + Description: `Params needed to access the source in the format of String-to-String (Key, Value) pairs.`, + Elem: &schema.Schema{Type: schema.TypeString}, + ExactlyOneOf: []string{"params", "json_params"}, + }, + "static_ip_enabled": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + Description: `Whether customer has enabled static IP addresses for this connector.`, + }, + "sync_mode": { + Type: schema.TypeString, + Optional: true, + Description: `The data synchronization mode supported by the data connector. The possible value can be: +'PERIODIC', 'STREAMING'.`, + }, + "action_state": { + Type: schema.TypeString, + Computed: true, + Description: `State of the action connector. This reflects whether the action connector +is initializing, active or has encountered errors. The possible value can be: +'STATE_UNSPECIFIED', 'CREATING', 'ACTIVE', 'FAILED', 'RUNNING', 'WARNING', +'INITIALIZATION_FAILED', 'UPDATING'.`, + }, + "blocking_reasons": { + Type: schema.TypeList, + Computed: true, + Description: `User actions that must be completed before the connector can start syncing data. +The possible values can be: 'ALLOWLIST_STATIC_IP', 'ALLOWLIST_IN_SERVICE_ATTACHMENT'.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "connector_type": { + Type: schema.TypeString, + Computed: true, + Description: `The type of connector. Each source can only map to one type. +For example, salesforce, confluence and jira have THIRD_PARTY connector +type. It is not mutable once set by system. The possible value can be: +'CONNECTOR_TYPE_UNSPECIFIED', 'THIRD_PARTY', 'GCP_FHIR', 'BIG_QUERY', +'GCS', 'GOOGLE_MAIL', 'GOOGLE_CALENDAR', 'GOOGLE_DRIVE', +'NATIVE_CLOUD_IDENTITY', 'THIRD_PARTY_FEDERATED', 'THIRD_PARTY_EUA', 'GCNV'.`, + }, + "create_time": { + Type: schema.TypeString, + Computed: true, + Description: `Timestamp when the DataConnector was created.`, + }, + "errors": { + Type: schema.TypeList, + Computed: true, + Description: `The errors from initialization or from the latest connector run.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "code": { + Type: schema.TypeInt, + Computed: true, + Description: `The status code, which should be an enum value of google.rpc.Code.`, + }, + "message": { + Type: schema.TypeString, + Computed: true, + Description: `A developer-facing error message, which should be in English.`, + }, + }, + }, + }, + "last_sync_time": { + Type: schema.TypeString, + Computed: true, + Description: `For periodic connectors only, the last time a data sync was completed.`, + }, + "latest_pause_time": { + Type: schema.TypeString, + Computed: true, + Description: `The most recent timestamp when this [DataConnector][] was paused, +affecting all functionalities such as data synchronization. +Pausing a connector has the following effects: + - All functionalities, including data synchronization, are halted. + - Any ongoing data synchronization job will be canceled. + - No future data synchronization runs will be scheduled nor can be +triggered.`, + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: `The full resource name of the Data Connector. +Format: 'projects/*/locations/*/collections/*/dataConnector'.`, + }, + "private_connectivity_project_id": { + Type: schema.TypeString, + Computed: true, + Description: `The tenant project ID associated with private connectivity connectors. +This project must be allowlisted by in order for the connector to function.`, + }, + "realtime_state": { + Type: schema.TypeString, + Computed: true, + Description: `The real-time sync state. The possible values can be: +'STATE_UNSPECIFIED', 'CREATING', 'ACTIVE', 'FAILED', 'RUNNING', 'WARNING', +'INITIALIZATION_FAILED', 'UPDATING'.`, + }, + "state": { + Type: schema.TypeString, + Computed: true, + Description: `The state of connector. The possible value can be: +'STATE_UNSPECIFIED', 'CREATING', 'ACTIVE', 'FAILED', 'RUNNING', 'WARNING', +'INITIALIZATION_FAILED', 'UPDATING'.`, + }, + "static_ip_addresses": { + Type: schema.TypeList, + Computed: true, + Description: `The static IP addresses used by this connector.`, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "update_time": { + Type: schema.TypeString, + Computed: true, + Description: `Timestamp when the DataConnector was updated.`, + }, + "project": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + }, + UseJSONNumber: true, + } +} diff --git a/google/services/discoveryengine/resource_discovery_engine_data_connector_generated_meta.yaml b/google/services/discoveryengine/resource_discovery_engine_data_connector_generated_meta.yaml index 2960026463a..36be6278a08 100644 --- a/google/services/discoveryengine/resource_discovery_engine_data_connector_generated_meta.yaml +++ b/google/services/discoveryengine/resource_discovery_engine_data_connector_generated_meta.yaml @@ -8,11 +8,13 @@ api_variant_patterns: - 'projects/{project}/locations/{location}/collections/{collection}/dataConnector' fields: - field: 'action_state' + - field: 'auto_run_disabled' - field: 'blocking_reasons' - field: 'collection_display_name' provider_only: true - field: 'collection_id' provider_only: true + - field: 'connector_modes' - field: 'connector_type' - field: 'create_time' - field: 'data_source' @@ -20,8 +22,11 @@ fields: - field: 'entities.entity_name' - field: 'entities.key_property_mappings' - field: 'entities.params' + json: true - field: 'errors.code' - field: 'errors.message' + - field: 'incremental_refresh_interval' + - field: 'incremental_sync_disabled' - field: 'json_params' - field: 'kms_key_name' - field: 'last_sync_time' @@ -36,4 +41,5 @@ fields: - field: 'state' - field: 'static_ip_addresses' - field: 'static_ip_enabled' + - field: 'sync_mode' - field: 'update_time' diff --git a/google/services/discoveryengine/resource_discovery_engine_data_connector_generated_test.go b/google/services/discoveryengine/resource_discovery_engine_data_connector_generated_test.go index 85469ac184e..f4a354e9bde 100644 --- a/google/services/discoveryengine/resource_discovery_engine_data_connector_generated_test.go +++ b/google/services/discoveryengine/resource_discovery_engine_data_connector_generated_test.go @@ -30,12 +30,10 @@ import ( transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" ) -func TestAccDiscoveryEngineDataConnector_discoveryengineDataconnectorJiraBasicExample(t *testing.T) { +func TestAccDiscoveryEngineDataConnector_discoveryengineDataconnectorServicenowBasicExample(t *testing.T) { t.Parallel() context := map[string]interface{}{ - "client_id": "tf-test-client-id", - "client_secret": "tf-test-client-secret", "random_suffix": acctest.RandString(t, 10), } @@ -45,49 +43,69 @@ func TestAccDiscoveryEngineDataConnector_discoveryengineDataconnectorJiraBasicEx CheckDestroy: testAccCheckDiscoveryEngineDataConnectorDestroyProducer(t), Steps: []resource.TestStep{ { - Config: testAccDiscoveryEngineDataConnector_discoveryengineDataconnectorJiraBasicExample(context), + Config: testAccDiscoveryEngineDataConnector_discoveryengineDataconnectorServicenowBasicExample(context), }, { - ResourceName: "google_discovery_engine_data_connector.jira-basic", + ResourceName: "google_discovery_engine_data_connector.servicenow-basic", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"collection_display_name", "collection_id", "json_params", "location", "params"}, + ImportStateVerifyIgnore: []string{"auto_run_disabled", "collection_display_name", "collection_id", "incremental_sync_disabled", "json_params", "location", "params", "sync_mode"}, }, }, }) } -func testAccDiscoveryEngineDataConnector_discoveryengineDataconnectorJiraBasicExample(context map[string]interface{}) string { +func testAccDiscoveryEngineDataConnector_discoveryengineDataconnectorServicenowBasicExample(context map[string]interface{}) string { return acctest.Nprintf(` -resource "google_discovery_engine_data_connector" "jira-basic" { - location = "global" - collection_id = "tf-test-collection-id%{random_suffix}" - collection_display_name = "tf-test-dataconnector-jira" - data_source = "jira" +resource "google_discovery_engine_data_connector" "servicenow-basic" { + location = "global" + collection_id = "tf-test-collection-id%{random_suffix}" + collection_display_name = "tf-test-dataconnector-servicenow" + data_source = "servicenow" params = { - instance_id = "33db20a3-dc45-4305-a505-d70b68599840" - instance_uri = "https://vaissptbots1.atlassian.net/" - client_secret = "%{client_secret}" - client_id = "%{client_id}" - refresh_token = "fill-in-the-blank" + auth_type = "OAUTH_PASSWORD_GRANT" + instance_uri = "https://gcpconnector1.service-now.com/" + client_id = "SECRET_MANAGER_RESOURCE_NAME" + client_secret = "SECRET_MANAGER_RESOURCE_NAME" + static_ip_enabled = "false" + user_account = "connectorsuserqa@google.com" + password = "SECRET_MANAGER_RESOURCE_NAME" } - refresh_interval = "86400s" + refresh_interval = "86400s" + incremental_refresh_interval = "21600s" entities { - entity_name = "project" + entity_name = "catalog" + params = jsonencode({ + "inclusion_filters": { + "knowledgeBaseSysId": [ + "123" + ] + } + }) } entities { - entity_name = "issue" + entity_name = "incident" + params = jsonencode({ + "inclusion_filters": { + "knowledgeBaseSysId": [ + "123" + ] + } + }) } entities { - entity_name = "attachment" + entity_name = "knowledge_base" + params = jsonencode({ + "inclusion_filters": { + "knowledgeBaseSysId": [ + "123" + ] + } + }) } - entities { - entity_name = "comment" - } - entities { - entity_name = "worklog" - } - static_ip_enabled = true + static_ip_enabled = false + connector_modes = ["DATA_INGESTION"] + sync_mode = "PERIODIC" } `, context) } diff --git a/google/services/discoveryengine/resource_discovery_engine_data_connector_test.go b/google/services/discoveryengine/resource_discovery_engine_data_connector_test.go index b3f860ce97a..16f7d310e60 100644 --- a/google/services/discoveryengine/resource_discovery_engine_data_connector_test.go +++ b/google/services/discoveryengine/resource_discovery_engine_data_connector_test.go @@ -17,20 +17,20 @@ package discoveryengine_test import ( + "testing" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-provider-google/google/acctest" - "testing" + "github.com/hashicorp/terraform-provider-google/google/services/discoveryengine" ) -func TestAccDiscoveryEngineDataConnector_discoveryengineDataconnectorJiraBasicExample_update(t *testing.T) { +func TestAccDiscoveryEngineDataConnector_discoveryengineDataconnectorServicenowBasicExample_update(t *testing.T) { // Skips this update test due to duration and flakiness. t.Skip() t.Parallel() context := map[string]interface{}{ - "client_id": "tf-test-client-id", - "client_secret": "tf-test-client-secret", "random_suffix": acctest.RandString(t, 10), } @@ -42,19 +42,19 @@ func TestAccDiscoveryEngineDataConnector_discoveryengineDataconnectorJiraBasicEx }, Steps: []resource.TestStep{ { - Config: testAccDiscoveryEngineDataConnector_discoveryengineDataconnectorJiraBasicExample_basic(context), + Config: testAccDiscoveryEngineDataConnector_discoveryengineDataconnectorServicenowBasicExample_basic(context), }, { - ResourceName: "google_discovery_engine_data_connector.jira-basic", + ResourceName: "google_discovery_engine_data_connector.servicenow-basic", ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"collection_display_name", "collection_id", "location", "params"}, }, { - Config: testAccDiscoveryEngineDataConnector_discoveryengineDataconnectorJiraBasicExample_update(context), + Config: testAccDiscoveryEngineDataConnector_discoveryengineDataconnectorServicenowBasicExample_update(context), }, { - ResourceName: "google_discovery_engine_data_connector.jira-basic", + ResourceName: "google_discovery_engine_data_connector.servicenow-basic", ImportState: true, ImportStateVerify: true, ImportStateVerifyIgnore: []string{"collection_display_name", "collection_id", "location", "params"}, @@ -63,74 +63,145 @@ func TestAccDiscoveryEngineDataConnector_discoveryengineDataconnectorJiraBasicEx }) } -func testAccDiscoveryEngineDataConnector_discoveryengineDataconnectorJiraBasicExample_basic(context map[string]interface{}) string { +func testAccDiscoveryEngineDataConnector_discoveryengineDataconnectorServicenowBasicExample_basic(context map[string]interface{}) string { return acctest.Nprintf(` -resource "google_discovery_engine_data_connector" "jira-basic" { - location = "global" - collection_id = "tf-test-collection-id%{random_suffix}" - collection_display_name = "tf-test-dataconnector-jira" - data_source = "jira" +resource "google_discovery_engine_data_connector" "servicenow-basic" { + location = "global" + collection_id = "tf-test-collection-id%{random_suffix}" + collection_display_name = "tf-test-dataconnector-servicenow" + data_source = "servicenow" params = { - instance_id = "33db20a3-dc45-4305-a505-d70b68599840" - instance_uri = "https://vaissptbots1.atlassian.net/" - client_secret = "%{client_secret}" - client_id = "%{client_id}" - refresh_token = "fill-in-the-blank" - } - refresh_interval = "86400s" - entities { - entity_name = "project" + auth_type = "OAUTH_PASSWORD_GRANT" + instance_uri = "https://gcpconnector1.service-now.com/" + client_id = "SECRET_MANAGER_RESOURCE_NAME" + client_secret = "SECRET_MANAGER_RESOURCE_NAME" + static_ip_enabled = "false" + user_account = "connectorsuserqa@google.com" + password = "SECRET_MANAGER_RESOURCE_NAME" } + refresh_interval = "86400s" entities { - entity_name = "issue" + entity_name = "catalog" + params = jsonencode({ + "inclusion_filters": { + "knowledgeBaseSysId": [ + "123" + ] + } + }) } entities { - entity_name = "attachment" + entity_name = "incident" + params = jsonencode({ + "inclusion_filters": { + "knowledgeBaseSysId": [ + "123" + ] + } + }) } entities { - entity_name = "comment" + entity_name = "knowledge_base" + params = jsonencode({ + "inclusion_filters": { + "knowledgeBaseSysId": [ + "123" + ] + } + }) } - entities { - entity_name = "worklog" - } - static_ip_enabled = true + static_ip_enabled = false + incremental_refresh_interval = "21600s" + connector_modes = ["DATA_INGESTION"] + sync_mode = "PERIODIC" + auto_run_disabled = true + incremental_sync_disabled = true } `, context) } -func testAccDiscoveryEngineDataConnector_discoveryengineDataconnectorJiraBasicExample_update(context map[string]interface{}) string { +func testAccDiscoveryEngineDataConnector_discoveryengineDataconnectorServicenowBasicExample_update(context map[string]interface{}) string { return acctest.Nprintf(` resource "time_sleep" "wait_1_hour" { create_duration = "3s" } -resource "google_discovery_engine_data_connector" "jira-basic" { - depends_on = [time_sleep.wait_1_hour] - location = "global" - collection_id = "tf-test-collection-id%{random_suffix}" - collection_display_name = "tf-test-dataconnector-jira" - data_source = "jira" +resource "google_discovery_engine_data_connector" "servicenow-basic" { + depends_on = [time_sleep.wait_1_hour] + location = "global" + collection_id = "tf-test-collection-id%{random_suffix}" + collection_display_name = "tf-test-dataconnector-servicenow" + data_source = "servicenow" params = { - max_qps = "100" + max_qps = "100" } - refresh_interval = "172800s" + refresh_interval = "172800s" entities { - entity_name = "project" + entity_name = "catalog" + params = jsonencode({ + "inclusion_filters": { + "knowledgeBaseSysId": [ + "123" + ] + } + }) } entities { - entity_name = "issue" + entity_name = "incident" + params = jsonencode({ + "inclusion_filters": { + "knowledgeBaseSysId": [ + "123" + ] + } + }) } entities { - entity_name = "attachment" + entity_name = "knowledge_base" + params = jsonencode({ + "inclusion_filters": { + "knowledgeBaseSysId": [ + "123" + ] + } + }) } - entities { - entity_name = "comment" - } - entities { - entity_name = "worklog" - } - static_ip_enabled = true + static_ip_enabled = false + incremental_refresh_interval = "21600s" + connector_modes = ["DATA_INGESTION"] + sync_mode = "PERIODIC" + auto_run_disabled = false + incremental_sync_disabled = false } `, context) } + +func TestAccDiscoveryEngineDataConnector_DataConnectorEntitiesParamsDiffSuppress(t *testing.T) { + cases := map[string]struct { + Old, New string + ExpectDiffSuppress bool + }{ + "Old empty JSON": { + Old: "{}", + New: "", + ExpectDiffSuppress: true, + }, + "New empty JSON": { + Old: "", + New: "{}", + ExpectDiffSuppress: true, + }, + "Diff not supressed": { + Old: "123", + New: "", + ExpectDiffSuppress: false, + }, + } + + for tn, tc := range cases { + if discoveryengine.DataConnectorEntitiesParamsDiffSuppress("entities_params_diff_supress", tc.Old, tc.New, nil) != tc.ExpectDiffSuppress { + t.Errorf("bad: %s, %q => %q expect DiffSuppress to return %t", tn, tc.Old, tc.New, tc.ExpectDiffSuppress) + } + } +} diff --git a/google/services/discoveryengine/resource_discovery_engine_search_engine.go b/google/services/discoveryengine/resource_discovery_engine_search_engine.go index e17c64930f8..ba34cfdf88e 100644 --- a/google/services/discoveryengine/resource_discovery_engine_search_engine.go +++ b/google/services/discoveryengine/resource_discovery_engine_search_engine.go @@ -152,6 +152,17 @@ The supported values: 'APP_TYPE_UNSPECIFIED', 'APP_TYPE_INTRANET'.`, Description: `The industry vertical that the engine registers. The restriction of the Engine industry vertical is based on DataStore: If unspecified, default to GENERIC. Vertical on Engine has to match vertical of the DataStore liniked to the engine. Default value: "GENERIC" Possible values: ["GENERIC", "MEDIA", "HEALTHCARE_FHIR"]`, Default: "GENERIC", }, + "kms_key_name": { + Type: schema.TypeString, + Optional: true, + Description: `The KMS key to be used to protect this Engine at creation time. + +Must be set for requests that need to comply with CMEK Org Policy +protections. + +If this field is set and processed successfully, the Engine will be +protected by the KMS key, as indicated in the cmek_config field.`, + }, "create_time": { Type: schema.TypeString, Computed: true, @@ -231,6 +242,12 @@ func resourceDiscoveryEngineSearchEngineCreate(d *schema.ResourceData, meta inte } else if v, ok := d.GetOkExists("features"); !tpgresource.IsEmptyValue(reflect.ValueOf(featuresProp)) && (ok || !reflect.DeepEqual(v, featuresProp)) { obj["features"] = featuresProp } + kmsKeyNameProp, err := expandDiscoveryEngineSearchEngineKmsKeyName(d.Get("kms_key_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("kms_key_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(kmsKeyNameProp)) && (ok || !reflect.DeepEqual(v, kmsKeyNameProp)) { + obj["kmsKeyName"] = kmsKeyNameProp + } obj, err = resourceDiscoveryEngineSearchEngineEncoder(d, meta, obj) if err != nil { @@ -409,6 +426,12 @@ func resourceDiscoveryEngineSearchEngineUpdate(d *schema.ResourceData, meta inte } else if v, ok := d.GetOkExists("features"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, featuresProp)) { obj["features"] = featuresProp } + kmsKeyNameProp, err := expandDiscoveryEngineSearchEngineKmsKeyName(d.Get("kms_key_name"), d, config) + if err != nil { + return err + } else if v, ok := d.GetOkExists("kms_key_name"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, kmsKeyNameProp)) { + obj["kmsKeyName"] = kmsKeyNameProp + } obj, err = resourceDiscoveryEngineSearchEngineEncoder(d, meta, obj) if err != nil { @@ -439,6 +462,10 @@ func resourceDiscoveryEngineSearchEngineUpdate(d *schema.ResourceData, meta inte if d.HasChange("features") { updateMask = append(updateMask, "features") } + + if d.HasChange("kms_key_name") { + updateMask = append(updateMask, "kmsKeyName") + } // updateMask is a URL parameter but not present in the schema, so ReplaceVars // won't set it url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")}) @@ -713,6 +740,10 @@ func expandDiscoveryEngineSearchEngineFeatures(v interface{}, d tpgresource.Terr return m, nil } +func expandDiscoveryEngineSearchEngineKmsKeyName(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) { + return v, nil +} + func resourceDiscoveryEngineSearchEngineEncoder(d *schema.ResourceData, meta interface{}, obj map[string]interface{}) (map[string]interface{}, error) { // hard code solutionType to "SOLUTION_TYPE_SEARCH" for search engine resource obj["solutionType"] = "SOLUTION_TYPE_SEARCH" diff --git a/google/services/discoveryengine/resource_discovery_engine_search_engine_generated_meta.yaml b/google/services/discoveryengine/resource_discovery_engine_search_engine_generated_meta.yaml index aca7ba92a01..f2d5c5bdf78 100644 --- a/google/services/discoveryengine/resource_discovery_engine_search_engine_generated_meta.yaml +++ b/google/services/discoveryengine/resource_discovery_engine_search_engine_generated_meta.yaml @@ -16,6 +16,7 @@ fields: provider_only: true - field: 'features' - field: 'industry_vertical' + - field: 'kms_key_name' - field: 'location' provider_only: true - field: 'name' diff --git a/google/services/discoveryengine/resource_discovery_engine_search_engine_generated_test.go b/google/services/discoveryengine/resource_discovery_engine_search_engine_generated_test.go index f5bea6e75fa..27465dc0751 100644 --- a/google/services/discoveryengine/resource_discovery_engine_search_engine_generated_test.go +++ b/google/services/discoveryengine/resource_discovery_engine_search_engine_generated_test.go @@ -49,7 +49,7 @@ func TestAccDiscoveryEngineSearchEngine_discoveryengineSearchengineBasicExample( ResourceName: "google_discovery_engine_search_engine.basic", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"collection_id", "engine_id", "location"}, + ImportStateVerifyIgnore: []string{"collection_id", "engine_id", "kms_key_name", "location"}, }, }, }) @@ -97,7 +97,7 @@ func TestAccDiscoveryEngineSearchEngine_discoveryengineSearchengineAgentspaceBas ResourceName: "google_discovery_engine_search_engine.agentspace_basic", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"collection_id", "engine_id", "location"}, + ImportStateVerifyIgnore: []string{"collection_id", "engine_id", "kms_key_name", "location"}, }, }, }) @@ -121,6 +121,7 @@ resource "google_discovery_engine_search_engine" "agentspace_basic" { display_name = "tf-test-agentspace-search-engine" data_store_ids = [google_discovery_engine_data_store.agentspace_basic.data_store_id] industry_vertical = "GENERIC" + app_type = "APP_TYPE_INTRANET" search_engine_config { } } diff --git a/google/services/discoveryengine/resource_discovery_engine_search_engine_test.go b/google/services/discoveryengine/resource_discovery_engine_search_engine_test.go index e973eecc35d..ff6dbed61d6 100644 --- a/google/services/discoveryengine/resource_discovery_engine_search_engine_test.go +++ b/google/services/discoveryengine/resource_discovery_engine_search_engine_test.go @@ -28,6 +28,7 @@ func TestAccDiscoveryEngineSearchEngine_discoveryengineSearchengineBasicExample_ context := map[string]interface{}{ "random_suffix": acctest.RandString(t, 10), + "kms_key_name": acctest.BootstrapKMSKeyWithPurposeInLocationAndName(t, "ENCRYPT_DECRYPT", "us", "tftest-shared-key-6").CryptoKey.Name, } acctest.VcrTest(t, resource.TestCase{ @@ -44,7 +45,7 @@ func TestAccDiscoveryEngineSearchEngine_discoveryengineSearchengineBasicExample_ ResourceName: "google_discovery_engine_search_engine.basic", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"engine_id", "collection_id", "location"}, + ImportStateVerifyIgnore: []string{"engine_id", "collection_id", "location", "kms_key_name"}, }, { Config: testAccDiscoveryEngineSearchEngine_discoveryengineSearchengineBasicExample_update(context), @@ -53,7 +54,7 @@ func TestAccDiscoveryEngineSearchEngine_discoveryengineSearchengineBasicExample_ ResourceName: "google_discovery_engine_search_engine.basic", ImportState: true, ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"engine_id", "collection_id", "location"}, + ImportStateVerifyIgnore: []string{"engine_id", "collection_id", "location", "kms_key_name"}, }, }, }) @@ -93,6 +94,7 @@ resource "google_discovery_engine_search_engine" "basic" { search_tier = "SEARCH_TIER_ENTERPRISE" search_add_ons = ["SEARCH_ADD_ON_LLM"] } + kms_key_name = "%{kms_key_name}" } `, context) } @@ -134,6 +136,7 @@ resource "google_discovery_engine_search_engine" "basic" { features = { feedback = "FEATURE_STATE_OFF" } + kms_key_name = "%{kms_key_name}" } `, context) } diff --git a/website/docs/r/discovery_engine_data_connector.html.markdown b/website/docs/r/discovery_engine_data_connector.html.markdown index 54db80f9b72..167cecb7ca9 100644 --- a/website/docs/r/discovery_engine_data_connector.html.markdown +++ b/website/docs/r/discovery_engine_data_connector.html.markdown @@ -35,43 +35,63 @@ To get more information about DataConnector, see: * [Introduction](https://cloud.google.com/agentspace/docs/introduction-to-connectors-and-data-stores)
- + Open in Cloud Shell
-## Example Usage - Discoveryengine Dataconnector Jira Basic +## Example Usage - Discoveryengine Dataconnector Servicenow Basic ```hcl -resource "google_discovery_engine_data_connector" "jira-basic" { - location = "global" - collection_id = "collection-id" - collection_display_name = "tf-test-dataconnector-jira" - data_source = "jira" +resource "google_discovery_engine_data_connector" "servicenow-basic" { + location = "global" + collection_id = "collection-id" + collection_display_name = "tf-test-dataconnector-servicenow" + data_source = "servicenow" params = { - instance_id = "33db20a3-dc45-4305-a505-d70b68599840" - instance_uri = "https://vaissptbots1.atlassian.net/" - client_secret = "client-secret" - client_id = "client-id" - refresh_token = "fill-in-the-blank" + auth_type = "OAUTH_PASSWORD_GRANT" + instance_uri = "https://gcpconnector1.service-now.com/" + client_id = "SECRET_MANAGER_RESOURCE_NAME" + client_secret = "SECRET_MANAGER_RESOURCE_NAME" + static_ip_enabled = "false" + user_account = "connectorsuserqa@google.com" + password = "SECRET_MANAGER_RESOURCE_NAME" } - refresh_interval = "86400s" + refresh_interval = "86400s" + incremental_refresh_interval = "21600s" entities { - entity_name = "project" + entity_name = "catalog" + params = jsonencode({ + "inclusion_filters": { + "knowledgeBaseSysId": [ + "123" + ] + } + }) } entities { - entity_name = "issue" + entity_name = "incident" + params = jsonencode({ + "inclusion_filters": { + "knowledgeBaseSysId": [ + "123" + ] + } + }) } entities { - entity_name = "attachment" + entity_name = "knowledge_base" + params = jsonencode({ + "inclusion_filters": { + "knowledgeBaseSysId": [ + "123" + ] + } + }) } - entities { - entity_name = "comment" - } - entities { - entity_name = "worklog" - } - static_ip_enabled = true + static_ip_enabled = false + connector_modes = ["DATA_INGESTION"] + sync_mode = "PERIODIC" } ``` @@ -140,6 +160,34 @@ The following arguments are supported: (Optional) Whether customer has enabled static IP addresses for this connector. +* `connector_modes` - + (Optional) + The modes enabled for this connector. The possible value can be: + 'DATA_INGESTION', 'ACTIONS', 'FEDERATED' + 'EUA', 'FEDERATED_AND_EUA'. + +* `sync_mode` - + (Optional) + The data synchronization mode supported by the data connector. The possible value can be: + 'PERIODIC', 'STREAMING'. + +* `incremental_refresh_interval` - + (Optional) + The refresh interval specifically for incremental data syncs. If unset, + incremental syncs will use the default from env, set to 3hrs. + The minimum is 30 minutes and maximum is 7 days. Applicable to only 3P + connectors. When the refresh interval is + set to the same value as the incremental refresh interval, incremental + sync will be disabled. + +* `auto_run_disabled` - + (Optional) + Indicates whether full syncs are paused for this connector + +* `incremental_sync_disabled` - + (Optional) + Indicates whether incremental syncs are paused for this connector. + * `project` - (Optional) The ID of the project in which the resource belongs. If it is not provided, the provider project is used. diff --git a/website/docs/r/discovery_engine_search_engine.html.markdown b/website/docs/r/discovery_engine_search_engine.html.markdown index 301f464d0d5..578d1f0baf5 100644 --- a/website/docs/r/discovery_engine_search_engine.html.markdown +++ b/website/docs/r/discovery_engine_search_engine.html.markdown @@ -83,6 +83,7 @@ resource "google_discovery_engine_search_engine" "agentspace_basic" { display_name = "tf-test-agentspace-search-engine" data_store_ids = [google_discovery_engine_data_store.agentspace_basic.data_store_id] industry_vertical = "GENERIC" + app_type = "APP_TYPE_INTRANET" search_engine_config { } } @@ -139,6 +140,14 @@ The following arguments are supported: (Optional) A map of the feature config for the engine to opt in or opt out of features. +* `kms_key_name` - + (Optional) + The KMS key to be used to protect this Engine at creation time. + Must be set for requests that need to comply with CMEK Org Policy + protections. + If this field is set and processed successfully, the Engine will be + protected by the KMS key, as indicated in the cmek_config field. + * `project` - (Optional) The ID of the project in which the resource belongs. If it is not provided, the provider project is used.