Skip to content

Commit 4213468

Browse files
authored
Fixed updating owners for UC resources (#3189)
* Fix updating owners * fix tests * - * test * integration test * test * Test * Update connection resource * restore connection * restore connection * update * docs * docs * docs
1 parent 3f8144f commit 4213468

17 files changed

+144
-53
lines changed

catalog/resource_catalog.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ func ResourceCatalog() common.Resource {
148148
}
149149
}
150150

151+
if !d.HasChangeExcept("owner") {
152+
return nil
153+
}
154+
151155
updateCatalogRequest.Owner = ""
152156
ci, err := w.Catalogs.Update(ctx, updateCatalogRequest)
153157

catalog/resource_external_location.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ func ResourceExternalLocation() common.Resource {
108108
}
109109
}
110110

111+
if !d.HasChangeExcept("owner") {
112+
return nil
113+
}
114+
111115
updateExternalLocationRequest.Owner = ""
112116
_, err = w.ExternalLocations.Update(ctx, updateExternalLocationRequest)
113117
if err != nil {

catalog/resource_metastore.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ func ResourceMetastore() common.Resource {
138138
return err
139139
}
140140
}
141+
142+
if !d.HasChangeExcept("owner") {
143+
return nil
144+
}
145+
141146
update.Owner = ""
142147
_, err := acc.Metastores.Update(ctx, catalog.AccountsUpdateMetastore{
143148
MetastoreId: d.Id(),
@@ -171,6 +176,11 @@ func ResourceMetastore() common.Resource {
171176
return err
172177
}
173178
}
179+
180+
if !d.HasChangeExcept("owner") {
181+
return nil
182+
}
183+
174184
update.Owner = ""
175185
_, err := w.Metastores.Update(ctx, update)
176186
if err != nil {

catalog/resource_metastore_test.go

Lines changed: 44 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -172,14 +172,42 @@ func TestUpdateMetastore_NoChanges(t *testing.T) {
172172
StorageRoot: "s3://b/abc",
173173
Name: "abc",
174174
}, nil)
175+
},
176+
Resource: ResourceMetastore(),
177+
ID: "abc",
178+
Update: true,
179+
RequiresNew: true,
180+
InstanceState: map[string]string{
181+
"name": "abc",
182+
"storage_root": "s3:/a",
183+
"owner": "admin",
184+
"delta_sharing_scope": "INTERNAL_AND_EXTERNAL",
185+
"delta_sharing_recipient_token_lifetime_in_seconds": "1002",
186+
},
187+
HCL: `
188+
name = "abc"
189+
storage_root = "s3:/a"
190+
owner = "admin"
191+
delta_sharing_scope = "INTERNAL_AND_EXTERNAL"
192+
delta_sharing_recipient_token_lifetime_in_seconds = 1002
193+
`,
194+
}.ApplyNoError(t)
195+
}
196+
197+
func TestUpdateMetastore_OnlyOwnerChanges(t *testing.T) {
198+
qa.ResourceFixture{
199+
MockWorkspaceClientFunc: func(w *mocks.MockWorkspaceClient) {
200+
e := w.GetMockMetastoresAPI().EXPECT()
175201
e.Update(mock.Anything, catalog.UpdateMetastore{
176-
Id: "abc",
177-
Name: "abc",
178-
DeltaSharingScope: "INTERNAL_AND_EXTERNAL",
179-
DeltaSharingRecipientTokenLifetimeInSeconds: 1002,
180-
ForceSendFields: []string{"DeltaSharingRecipientTokenLifetimeInSeconds"},
202+
Id: "abc",
203+
Owner: "updatedOwner",
181204
}).Return(&catalog.MetastoreInfo{
182-
Name: "a",
205+
Name: "abc",
206+
Owner: "updatedOwner",
207+
}, nil)
208+
e.GetById(mock.Anything, "abc").Return(&catalog.MetastoreInfo{
209+
Name: "abc",
210+
Owner: "updatedOwner",
183211
DeltaSharingScope: "INTERNAL_AND_EXTERNAL",
184212
DeltaSharingRecipientTokenLifetimeInSeconds: 1002,
185213
}, nil)
@@ -198,14 +226,14 @@ func TestUpdateMetastore_NoChanges(t *testing.T) {
198226
HCL: `
199227
name = "abc"
200228
storage_root = "s3:/a"
201-
owner = "admin"
229+
owner = "updatedOwner"
202230
delta_sharing_scope = "INTERNAL_AND_EXTERNAL"
203231
delta_sharing_recipient_token_lifetime_in_seconds = 1002
204232
`,
205233
}.ApplyNoError(t)
206234
}
207235

208-
func TestUpdateMetastore_OwnerChanges(t *testing.T) {
236+
func TestUpdateMetastore_OwnerAndOtherChanges(t *testing.T) {
209237
qa.ResourceFixture{
210238
MockWorkspaceClientFunc: func(w *mocks.MockWorkspaceClient) {
211239
e := w.GetMockMetastoresAPI().EXPECT()
@@ -220,19 +248,18 @@ func TestUpdateMetastore_OwnerChanges(t *testing.T) {
220248
Id: "abc",
221249
Name: "abc",
222250
DeltaSharingScope: "INTERNAL_AND_EXTERNAL",
223-
DeltaSharingRecipientTokenLifetimeInSeconds: 1002,
251+
DeltaSharingRecipientTokenLifetimeInSeconds: 1004,
224252
ForceSendFields: []string{"DeltaSharingRecipientTokenLifetimeInSeconds"},
225253
}).Return(&catalog.MetastoreInfo{
226-
Name: "a",
227254
Owner: "updatedOwner",
228255
DeltaSharingScope: "INTERNAL_AND_EXTERNAL",
229-
DeltaSharingRecipientTokenLifetimeInSeconds: 1002,
256+
DeltaSharingRecipientTokenLifetimeInSeconds: 1004,
230257
}, nil)
231258
e.GetById(mock.Anything, "abc").Return(&catalog.MetastoreInfo{
232259
Name: "abc",
233260
Owner: "updatedOwner",
234261
DeltaSharingScope: "INTERNAL_AND_EXTERNAL",
235-
DeltaSharingRecipientTokenLifetimeInSeconds: 1002,
262+
DeltaSharingRecipientTokenLifetimeInSeconds: 1004,
236263
}, nil)
237264
},
238265
Resource: ResourceMetastore(),
@@ -251,7 +278,7 @@ func TestUpdateMetastore_OwnerChanges(t *testing.T) {
251278
storage_root = "s3:/a"
252279
owner = "updatedOwner"
253280
delta_sharing_scope = "INTERNAL_AND_EXTERNAL"
254-
delta_sharing_recipient_token_lifetime_in_seconds = 1002
281+
delta_sharing_recipient_token_lifetime_in_seconds = 1004
255282
`,
256283
}.ApplyNoError(t)
257284
}
@@ -271,7 +298,7 @@ func TestUpdateMetastore_Rollback(t *testing.T) {
271298
Id: "abc",
272299
Name: "abc",
273300
DeltaSharingScope: "INTERNAL_AND_EXTERNAL",
274-
DeltaSharingRecipientTokenLifetimeInSeconds: 1002,
301+
DeltaSharingRecipientTokenLifetimeInSeconds: 1004,
275302
ForceSendFields: []string{"DeltaSharingRecipientTokenLifetimeInSeconds"},
276303
}).Return(nil, errors.New("Something unexpected happened"))
277304
e.Update(mock.Anything, catalog.UpdateMetastore{
@@ -298,7 +325,7 @@ func TestUpdateMetastore_Rollback(t *testing.T) {
298325
storage_root = "s3:/a"
299326
owner = "updatedOwner"
300327
delta_sharing_scope = "INTERNAL_AND_EXTERNAL"
301-
delta_sharing_recipient_token_lifetime_in_seconds = 1002
328+
delta_sharing_recipient_token_lifetime_in_seconds = 1004
302329
`,
303330
}.Apply(t)
304331
qa.AssertErrorStartsWith(t, err, "Something unexpected happened")
@@ -507,22 +534,6 @@ func TestUpdateAccountMetastore_NoChanges(t *testing.T) {
507534
qa.ResourceFixture{
508535
MockAccountClientFunc: func(a *mocks.MockAccountClient) {
509536
e := a.GetMockAccountMetastoresAPI().EXPECT()
510-
e.Update(mock.Anything, catalog.AccountsUpdateMetastore{
511-
MetastoreId: "abc",
512-
MetastoreInfo: &catalog.UpdateMetastore{
513-
Id: "abc",
514-
Name: "abc",
515-
DeltaSharingScope: "INTERNAL_AND_EXTERNAL",
516-
DeltaSharingRecipientTokenLifetimeInSeconds: 1002,
517-
ForceSendFields: []string{"DeltaSharingRecipientTokenLifetimeInSeconds"},
518-
},
519-
}).Return(&catalog.AccountsMetastoreInfo{
520-
MetastoreInfo: &catalog.MetastoreInfo{
521-
Name: "abc",
522-
DeltaSharingScope: "INTERNAL_AND_EXTERNAL",
523-
DeltaSharingRecipientTokenLifetimeInSeconds: 1002,
524-
},
525-
}, nil)
526537
e.GetByMetastoreId(mock.Anything, "abc").Return(&catalog.AccountsMetastoreInfo{
527538
MetastoreInfo: &catalog.MetastoreInfo{
528539
StorageRoot: "s3://b/abc",
@@ -569,22 +580,6 @@ func TestUpdateAccountMetastore_OwnerChanges(t *testing.T) {
569580
Owner: "updatedOwner",
570581
},
571582
}, nil)
572-
e.Update(mock.Anything, catalog.AccountsUpdateMetastore{
573-
MetastoreId: "abc",
574-
MetastoreInfo: &catalog.UpdateMetastore{
575-
Id: "abc",
576-
Name: "abc",
577-
DeltaSharingScope: "INTERNAL_AND_EXTERNAL",
578-
DeltaSharingRecipientTokenLifetimeInSeconds: 1002,
579-
ForceSendFields: []string{"DeltaSharingRecipientTokenLifetimeInSeconds"},
580-
},
581-
}).Return(&catalog.AccountsMetastoreInfo{
582-
MetastoreInfo: &catalog.MetastoreInfo{
583-
Name: "abc",
584-
DeltaSharingScope: "INTERNAL_AND_EXTERNAL",
585-
DeltaSharingRecipientTokenLifetimeInSeconds: 1002,
586-
},
587-
}, nil)
588583
e.GetByMetastoreId(mock.Anything, "abc").Return(&catalog.AccountsMetastoreInfo{
589584
MetastoreInfo: &catalog.MetastoreInfo{
590585
StorageRoot: "s3://b/abc",
@@ -637,7 +632,7 @@ func TestUpdateAccountMetastore_Rollback(t *testing.T) {
637632
Id: "abc",
638633
Name: "abc",
639634
DeltaSharingScope: "INTERNAL_AND_EXTERNAL",
640-
DeltaSharingRecipientTokenLifetimeInSeconds: 1002,
635+
DeltaSharingRecipientTokenLifetimeInSeconds: 1004,
641636
ForceSendFields: []string{"DeltaSharingRecipientTokenLifetimeInSeconds"},
642637
},
643638
}).Return(nil, errors.New("Something unexpected happened"))
@@ -671,7 +666,7 @@ func TestUpdateAccountMetastore_Rollback(t *testing.T) {
671666
storage_root = "s3:/a"
672667
owner = "updatedOwner"
673668
delta_sharing_scope = "INTERNAL_AND_EXTERNAL"
674-
delta_sharing_recipient_token_lifetime_in_seconds = 1002
669+
delta_sharing_recipient_token_lifetime_in_seconds = 1004
675670
`,
676671
}.Apply(t)
677672
qa.AssertErrorStartsWith(t, err, "Something unexpected happened")

catalog/resource_schema.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ func ResourceSchema() common.Resource {
9999
}
100100
}
101101

102+
if !d.HasChangeExcept("owner") {
103+
return nil
104+
}
105+
102106
updateSchemaRequest.Owner = ""
103107
schema, err := w.Schemas.Update(ctx, updateSchemaRequest)
104108
if err != nil {

catalog/resource_share.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,10 @@ func ResourceShare() common.Resource {
237237
}
238238
}
239239

240+
if !d.HasChangeExcept("owner") {
241+
return nil
242+
}
243+
240244
err = NewSharesAPI(ctx, c).update(d.Id(), ShareUpdates{
241245
Updates: changes,
242246
})

catalog/resource_storage_credential.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,11 @@ func ResourceStorageCredential() common.Resource {
152152
return err
153153
}
154154
}
155+
156+
if !d.HasChangeExcept("owner") {
157+
return nil
158+
}
159+
155160
update.Owner = ""
156161
_, err := acc.StorageCredentials.Update(ctx, catalog.AccountsUpdateStorageCredential{
157162
CredentialInfo: &update,
@@ -191,6 +196,11 @@ func ResourceStorageCredential() common.Resource {
191196
return err
192197
}
193198
}
199+
200+
if !d.HasChangeExcept("owner") {
201+
return nil
202+
}
203+
194204
update.Owner = ""
195205
_, err = w.StorageCredentials.Update(ctx, update)
196206
if err != nil {

catalog/resource_volume.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ func ResourceVolume() common.Resource {
9393
}
9494
}
9595

96+
if !d.HasChangeExcept("owner") {
97+
return nil
98+
}
99+
96100
updateVolumeRequestContent.Owner = ""
97101
v, err := w.Volumes.Update(ctx, updateVolumeRequestContent)
98102
if err != nil {

docs/index.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,10 @@ Except for metastore, metastore assignment and storage credential objects, Unity
355355

356356
If you are configuring a new Databricks account for the first time, please create at least one workspace with an identity (user or service principal) that you intend to use for Unity Catalog rollout. You can then configure the provider using that identity and workspace to provision the required Unity Catalog resources.
357357

358+
## Special considerations for Unity Catalog Resources
359+
360+
When performing a single Terraform apply to update both the owner and other fields for Unity Catalog resources, the process first updates the owner, followed by the other fields using the new owner's permissions. If your principal is not the owner (specifically, the newly updated owner), you will not have the authority to modify those fields. In cases where you wish to change the owner to another individual and also update other fields, we recommend initially updating the fields using your principal, which should have owner permissions, and then updating the owner in a separate step.
361+
358362
## Miscellaneous configuration parameters
359363

360364
!> **Warning** Combination of `debug_headers` and `debug_truncate_bytes` results in dumping of sensitive information to logs. Use it for troubleshooting purposes only.

internal/acceptance/catalog_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,16 @@ func TestUcAccCatalogUpdate(t *testing.T) {
7070
}
7171
owner = "account users"
7272
}`,
73+
}, step{
74+
Template: `
75+
resource "databricks_catalog" "sandbox" {
76+
name = "sandbox{var.STICKY_RANDOM}"
77+
comment = "this catalog is managed by terraform"
78+
properties = {
79+
purpose = "testing"
80+
}
81+
owner = "{env.TEST_DATA_ENG_GROUP}"
82+
}`,
7383
}, step{
7484
Template: `
7585
resource "databricks_catalog" "sandbox" {

0 commit comments

Comments
 (0)