Skip to content

Commit e2fad79

Browse files
authored
[Feature] Proper support for file events for databricks_external_location (#4749)
## Changes <!-- Summary of your changes that are easy to understand --> Proper support of file events requires customization and additional workarounds for API problems. Resolves #4747, resolves #4748 ## Tests <!-- How is this tested? Please see the checklist below and also describe any other relevant tests --> - [x] `make test` run locally - [x] relevant change in `docs/` folder - [ ] covered with integration tests in `internal/acceptance` - [x] using Go SDK - [ ] using TF Plugin Framework
1 parent 9be583d commit e2fad79

File tree

4 files changed

+86
-17
lines changed

4 files changed

+86
-17
lines changed

NEXT_CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
### New Features and Improvements
88

9+
* Support configuration of file events in `databricks_external_location` [#4749](https://github.com/databricks/terraform-provider-databricks/pull/4749).
10+
911
### Bug Fixes
1012

1113
* Populate `partitions` when reading `databricks_sql_table` ([#4674](https://github.com/databricks/terraform-provider-databricks/pull/4674)).

catalog/resource_external_location.go

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,25 @@ func ResourceExternalLocation() common.Resource {
3838
for _, key := range []string{"created_at", "created_by", "credential_id", "updated_at", "updated_by", "browse_only"} {
3939
common.CustomizeSchemaPath(m, key).SetReadOnly()
4040
}
41+
// customize file event queue
42+
supportedQueues := []string{"managed_pubsub", "managed_aqs", "managed_sqs", "provided_pubsub", "provided_aqs", "provided_sqs"}
43+
for _, key := range supportedQueues {
44+
common.CustomizeSchemaPath(m, "file_event_queue", key, "managed_resource_id").SetReadOnly()
45+
conflicts := make([]string, 0, len(supportedQueues)-1)
46+
for _, otherKey := range supportedQueues {
47+
if key != otherKey {
48+
conflicts = append(conflicts, "file_event_queue.0."+otherKey)
49+
}
50+
}
51+
common.CustomizeSchemaPath(m, "file_event_queue", key).SetConflictsWith(conflicts)
52+
}
53+
common.CustomizeSchemaPath(m, "file_event_queue", "provided_pubsub", "subscription_name").SetRequired()
54+
common.CustomizeSchemaPath(m, "file_event_queue", "provided_aqs", "queue_url").SetRequired()
55+
common.CustomizeSchemaPath(m, "file_event_queue", "provided_sqs", "queue_url").SetRequired()
56+
common.CustomizeSchemaPath(m, "file_event_queue", "managed_aqs", "resource_group").SetRequired()
57+
common.CustomizeSchemaPath(m, "file_event_queue", "managed_aqs", "subscription_id").SetRequired()
58+
common.CustomizeSchemaPath(m, "file_event_queue").SetMaxItems(1)
59+
4160
return m
4261
})
4362
return common.Resource{
@@ -113,13 +132,37 @@ func ResourceExternalLocation() common.Resource {
113132
if !d.HasChangeExcept("owner") {
114133
return nil
115134
}
116-
if d.HasChange("read_only") {
117-
updateExternalLocationRequest.ForceSendFields = append(updateExternalLocationRequest.ForceSendFields, "ReadOnly")
135+
booleanFields := map[string]string{"read_only": "ReadOnly", "fallback": "Fallback", "enable_file_events": "EnableFileEvents"}
136+
for key, value := range booleanFields {
137+
if d.HasChange(key) {
138+
updateExternalLocationRequest.ForceSendFields = append(updateExternalLocationRequest.ForceSendFields, value)
139+
}
140+
}
141+
// ugly hack until API is fixed
142+
if updateExternalLocationRequest.FileEventQueue != nil {
143+
if updateExternalLocationRequest.FileEventQueue.ManagedAqs != nil {
144+
updateExternalLocationRequest.FileEventQueue.ManagedAqs.ManagedResourceId = ""
145+
}
146+
if updateExternalLocationRequest.FileEventQueue.ManagedPubsub != nil {
147+
updateExternalLocationRequest.FileEventQueue.ManagedPubsub.ManagedResourceId = ""
148+
}
149+
if updateExternalLocationRequest.FileEventQueue.ManagedSqs != nil {
150+
updateExternalLocationRequest.FileEventQueue.ManagedSqs.ManagedResourceId = ""
151+
}
152+
if updateExternalLocationRequest.FileEventQueue.ProvidedPubsub != nil {
153+
updateExternalLocationRequest.FileEventQueue.ProvidedPubsub.SubscriptionName = ""
154+
}
155+
if updateExternalLocationRequest.FileEventQueue.ProvidedAqs != nil {
156+
updateExternalLocationRequest.FileEventQueue.ProvidedAqs.QueueUrl = ""
157+
}
158+
if updateExternalLocationRequest.FileEventQueue.ProvidedSqs != nil {
159+
updateExternalLocationRequest.FileEventQueue.ProvidedSqs.QueueUrl = ""
160+
}
118161
}
119-
if d.HasChange("fallback") {
120-
updateExternalLocationRequest.ForceSendFields = append(updateExternalLocationRequest.ForceSendFields, "Fallback")
162+
// if file events are disabled we shouldn't send FileEventQueue
163+
if !updateExternalLocationRequest.EnableFileEvents {
164+
updateExternalLocationRequest.FileEventQueue = nil
121165
}
122-
123166
updateExternalLocationRequest.Owner = ""
124167
_, err = w.ExternalLocations.Update(ctx, updateExternalLocationRequest)
125168
if err != nil {

catalog/resource_external_location_test.go

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -372,12 +372,13 @@ func TestUpdateExternalLocation_FromReadOnly(t *testing.T) {
372372
Method: "PATCH",
373373
Resource: "/api/2.1/unity-catalog/external-locations/abc",
374374
ExpectedRequest: catalog.UpdateExternalLocation{
375-
Url: "s3://foo/bar",
376-
CredentialName: "bcd",
377-
Comment: "def",
378-
ReadOnly: false,
379-
Fallback: false,
380-
ForceSendFields: []string{"ReadOnly", "Fallback"},
375+
Url: "s3://foo/bar",
376+
CredentialName: "bcd",
377+
Comment: "def",
378+
ReadOnly: false,
379+
Fallback: false,
380+
EnableFileEvents: false,
381+
ForceSendFields: []string{"ReadOnly", "Fallback", "EnableFileEvents"},
381382
},
382383
},
383384
{
@@ -396,12 +397,13 @@ func TestUpdateExternalLocation_FromReadOnly(t *testing.T) {
396397
Update: true,
397398
ID: "abc",
398399
InstanceState: map[string]string{
399-
"name": "abc",
400-
"url": "s3://foo/bar",
401-
"credential_name": "abc",
402-
"comment": "def",
403-
"read_only": "true",
404-
"fallback": "true",
400+
"name": "abc",
401+
"url": "s3://foo/bar",
402+
"credential_name": "abc",
403+
"comment": "def",
404+
"read_only": "true",
405+
"fallback": "true",
406+
"enable_file_events": "true",
405407
},
406408
HCL: `
407409
name = "abc"
@@ -410,6 +412,7 @@ func TestUpdateExternalLocation_FromReadOnly(t *testing.T) {
410412
comment = "def"
411413
read_only = false
412414
fallback = false
415+
enable_file_events = false
413416
`,
414417
}.ApplyNoError(t)
415418
}

docs/resources/external_location.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,33 @@ The following arguments are required:
126126
- `skip_validation` - (Optional) Suppress validation errors if any & force save the external location
127127
- `fallback` - (Optional) Indicates whether fallback mode is enabled for this external location. When fallback mode is enabled (disabled by default), the access to the location falls back to cluster credentials if UC credentials are not sufficient.
128128
- `read_only` - (Optional) Indicates whether the external location is read-only.
129+
- `enable_file_events` - (Optional) indicates if managed file events are enabled for this external location. Requires `file_event_queue` block.
129130
- `force_destroy` - (Optional) Destroy external location regardless of its dependents.
130131
- `force_update` - (Optional) Update external location regardless of its dependents.
131132
- `access_point` - (Optional) The ARN of the s3 access point to use with the external location (AWS).
132133
- `encryption_details` - (Optional) The options for Server-Side Encryption to be used by each Databricks s3 client when connecting to S3 cloud storage (AWS).
133134
- `isolation_mode` - (Optional) Whether the external location is accessible from all workspaces or a specific set of workspaces. Can be `ISOLATION_MODE_ISOLATED` or `ISOLATION_MODE_OPEN`. Setting the external location to `ISOLATION_MODE_ISOLATED` will automatically allow access from the current workspace.
134135

136+
### file_event_queue block
137+
138+
The `file_event_queue` block supports the following:
139+
140+
- `managed_pubsub` - (Optional) Configuration for managed Google Cloud Pub/Sub queue.
141+
- `managed_resource_id` - (Computed) The ID of the managed resource.
142+
- `managed_aqs` - (Optional) Configuration for managed Azure Queue Storage queue.
143+
- `managed_resource_id` - (Computed) The ID of the managed resource.
144+
- `resource_group` - (Required) The Azure resource group.
145+
- `subscription_id` - (Required) The Azure subscription ID.
146+
- `managed_sqs` - (Optional) Configuration for managed Amazon SQS queue.
147+
- `managed_resource_id` - (Computed) The ID of the managed resource.
148+
- `provided_pubsub` - (Optional) Configuration for provided Google Cloud Pub/Sub queue.
149+
- `subscription_name` - (Required) The name of the subscription.
150+
- `provided_aqs` - (Optional) Configuration for provided Azure Storage Queue.
151+
- `queue_url` - (Required) The URL of the queue.
152+
- `provided_sqs` - (Optional) Configuration for provided Amazon SQS queue.
153+
- `queue_url` - (Required) The URL of the SQS queue.
154+
155+
135156
## Attribute Reference
136157

137158
In addition to all arguments above, the following attributes are exported:

0 commit comments

Comments
 (0)