Skip to content

Commit e693fab

Browse files
alexottrauchy
andauthored
[Exporter] Added support for UC Tag policies (#5213)
## Changes <!-- Summary of your changes that are easy to understand --> ## 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 - [x] using TF Plugin Framework - [x] has entry in `NEXT_CHANGELOG.md` file Co-authored-by: Omer Lachish <[email protected]>
1 parent 0c41b93 commit e693fab

File tree

6 files changed

+133
-0
lines changed

6 files changed

+133
-0
lines changed

NEXT_CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
* Added support for `databricks_data_quality_monitor` resource ([#5193](https://github.com/databricks/terraform-provider-databricks/pull/5193)).
2929
* Fix typo in the name of environment variable ([#5158](https://github.com/databricks/terraform-provider-databricks/pull/5158)).
3030
* Export permission assignments on workspace level ([#5169](https://github.com/databricks/terraform-provider-databricks/pull/5169)).
31+
* Added support for UC Tag policies ([#5213](https://github.com/databricks/terraform-provider-databricks/pull/5213)).
3132
* Added support for Databricks Apps resources ([#5208](https://github.com/databricks/terraform-provider-databricks/pull/5208)).
3233
* Added support for Database Instance resource (aka Lakebase) ([#5212](https://github.com/databricks/terraform-provider-databricks/pull/5212)).
3334

docs/guides/experimental-exporter.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ Services could be specified in combination with predefined aliases (`all` - for
213213
* `uc-shares` - **listing** [databricks_share](../resources/share.md) and [databricks_recipient](../resources/recipient.md)
214214
* `uc-storage-credentials` - **listing** exports [databricks_storage_credential](../resources/storage_credential.md) resources on workspace or account level.
215215
* `uc-system-schemas` - **listing** exports [databricks_system_schema](../resources/system_schema.md) resources for the UC metastore of the current workspace.
216+
* `uc-tags` - **listing** exports [databricks_tag_policy](../resources/tag_policy.md) resources.
216217
* `uc-tables` - **listing** (*we can't list directly, only via dependencies to top-level object*) [databricks_sql_table](../resources/sql_table.md) resource.
217218
* `uc-volumes` - **listing** (*we can't list directly, only via dependencies to top-level object*) [databricks_volume](../resources/volume.md)
218219
* `users` - **listing** [databricks_user](../resources/user.md) and [databricks_service_principal](../resources/service_principal.md) are written to their own files, simply because of their number. If Identity Federation is enabled on the workspace (when UC Metastore is attached), then users and service principals are exposed as data sources because they are defined on an account level. See the note above on how to perform migration between workspaces with Identity Federation enabled.
@@ -315,6 +316,7 @@ Exporter aims to generate HCL code for most of the resources within the Databric
315316
| [databricks_sql_widget](../resources/sql_widget.md) | Yes | Yes | Yes | No |
316317
| [databricks_storage_credential](../resources/storage_credential.md) | Yes | Yes | Yes | No |
317318
| [databricks_system_schema](../resources/system_schema.md) | Yes | No | Yes | No |
319+
| [databricks_tag_policy](../resources/tag_policy.md) | Yes | No | Yes | No |
318320
| [databricks_token](../resources/token.md) | Not Applicable | No | Yes | No |
319321
| [databricks_user](../resources/user.md) | Yes | No | Yes | Yes |
320322
| [databricks_user_instance_profile](../resources/user_instance_profile.md) | No | No | No | No |

exporter/exporter_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/databricks/databricks-sdk-go/service/settings"
2828
"github.com/databricks/databricks-sdk-go/service/sharing"
2929
sdk_sql "github.com/databricks/databricks-sdk-go/service/sql"
30+
"github.com/databricks/databricks-sdk-go/service/tags"
3031
sdk_vs "github.com/databricks/databricks-sdk-go/service/vectorsearch"
3132
sdk_workspace "github.com/databricks/databricks-sdk-go/service/workspace"
3233

@@ -311,6 +312,13 @@ var emptyConnections = qa.HTTPFixture{
311312
Response: sdk_uc.ListConnectionsResponse{},
312313
}
313314

315+
var emptyTagPolicies = qa.HTTPFixture{
316+
Method: "GET",
317+
Resource: "/api/2.1/tag-policies?",
318+
Response: tags.ListTagPoliciesResponse{},
319+
ReuseRequest: true,
320+
}
321+
314322
var emptyRepos = qa.HTTPFixture{
315323
Method: "GET",
316324
ReuseRequest: true,
@@ -566,6 +574,7 @@ func TestImportingUsersGroupsSecretScopes(t *testing.T) {
566574
emptyDataQualityMonitors,
567575
emptyDatabaseInstances,
568576
emptyConnections,
577+
emptyTagPolicies,
569578
emptyRecipients,
570579
emptyGitCredentials,
571580
emptyWorkspace,
@@ -846,6 +855,7 @@ func TestImportingNoResourcesError(t *testing.T) {
846855
emptyUcCredentials,
847856
emptyShares,
848857
emptyConnections,
858+
emptyTagPolicies,
849859
emptyRecipients,
850860
emptyModelServing,
851861
emptyMlflowWebhooks,

exporter/impl_uc.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/databricks/databricks-sdk-go/service/catalog"
1111
"github.com/databricks/databricks-sdk-go/service/dataquality"
12+
"github.com/databricks/databricks-sdk-go/service/tags"
1213
tf_uc "github.com/databricks/terraform-provider-databricks/catalog"
1314
"github.com/databricks/terraform-provider-databricks/common"
1415
data_quality_monitor "github.com/databricks/terraform-provider-databricks/internal/providers/pluginfw/products/data_quality_monitor"
@@ -674,6 +675,29 @@ func listArtifactAllowLists(ic *importContext) error {
674675
return nil
675676
}
676677

678+
func listTagPolicies(ic *importContext) error {
679+
tagPolicies, err := ic.workspaceClient.TagPolicies.ListTagPoliciesAll(ic.Context, tags.ListTagPoliciesRequest{})
680+
if err != nil {
681+
return err
682+
}
683+
i := 0
684+
for _, tagPolicy := range tagPolicies {
685+
i++
686+
if !ic.MatchesName(tagPolicy.TagKey) {
687+
continue
688+
}
689+
ic.Emit(&resource{
690+
Resource: "databricks_tag_policy",
691+
ID: tagPolicy.TagKey,
692+
})
693+
if i%50 == 0 {
694+
log.Printf("[INFO] Imported %d Tag Policies", i)
695+
}
696+
}
697+
log.Printf("[INFO] Listed %d Tag Policies", i)
698+
return nil
699+
}
700+
677701
func importSqlTable(ic *importContext, r *resource) error {
678702
tableFullName := r.ID
679703
ic.emitUCGrantsWithOwner("table/"+tableFullName, r)

exporter/impl_uc_test.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
package exporter
22

33
import (
4+
"context"
5+
"fmt"
6+
"os"
47
"testing"
58

9+
"github.com/databricks/databricks-sdk-go/service/tags"
10+
"github.com/databricks/terraform-provider-databricks/common"
11+
"github.com/databricks/terraform-provider-databricks/qa"
612
"github.com/stretchr/testify/assert"
713
)
814

@@ -26,3 +32,85 @@ func TestEmitUserSpOrGroup(t *testing.T) {
2632
assert.Contains(t, ic.testEmits, "databricks_group[<unknown>] (display_name: users @ test.com)")
2733

2834
}
35+
36+
func TestTagPolicyExport(t *testing.T) {
37+
qa.HTTPFixturesApply(t, []qa.HTTPFixture{
38+
meAdminFixture,
39+
noCurrentMetastoreAttached,
40+
{
41+
Method: "GET",
42+
Resource: "/api/2.1/tag-policies?",
43+
Response: tags.ListTagPoliciesResponse{
44+
TagPolicies: []tags.TagPolicy{
45+
{
46+
TagKey: "environment",
47+
Description: "Environment tag policy",
48+
Values: []tags.Value{
49+
{Name: "dev"},
50+
{Name: "staging"},
51+
{Name: "production"},
52+
},
53+
},
54+
{
55+
TagKey: "team",
56+
Description: "Team tag policy",
57+
Values: []tags.Value{
58+
{Name: "engineering"},
59+
{Name: "data"},
60+
},
61+
},
62+
},
63+
},
64+
},
65+
{
66+
Method: "GET",
67+
Resource: "/api/2.1/tag-policies/environment?",
68+
ReuseRequest: true,
69+
Response: tags.TagPolicy{
70+
TagKey: "environment",
71+
Description: "Environment tag policy",
72+
Values: []tags.Value{
73+
{Name: "dev"},
74+
{Name: "staging"},
75+
{Name: "production"},
76+
},
77+
},
78+
},
79+
{
80+
Method: "GET",
81+
Resource: "/api/2.1/tag-policies/team?",
82+
ReuseRequest: true,
83+
Response: tags.TagPolicy{
84+
TagKey: "team",
85+
Description: "Team tag policy",
86+
Values: []tags.Value{
87+
{Name: "engineering"},
88+
{Name: "data"},
89+
},
90+
},
91+
},
92+
}, func(ctx context.Context, client *common.DatabricksClient) {
93+
tmpDir := fmt.Sprintf("/tmp/tf-%s", qa.RandomName())
94+
defer os.RemoveAll(tmpDir)
95+
96+
ic := newImportContext(client)
97+
ic.noFormat = true
98+
ic.Directory = tmpDir
99+
ic.enableListing("uc-tags")
100+
ic.enableServices("uc-tags")
101+
102+
err := ic.Run()
103+
assert.NoError(t, err)
104+
105+
content, err := os.ReadFile(tmpDir + "/uc-tags.tf")
106+
assert.NoError(t, err)
107+
contentStr := normalizeWhitespace(string(content))
108+
assert.Contains(t, contentStr, `resource "databricks_tag_policy" "environment"`)
109+
assert.Contains(t, contentStr, `resource "databricks_tag_policy" "team"`)
110+
assert.Contains(t, contentStr, `tag_key = "environment"`)
111+
assert.Contains(t, contentStr, `description = "Environment tag policy"`)
112+
assert.Contains(t, contentStr, `name = "dev"`)
113+
assert.Contains(t, contentStr, `name = "staging"`)
114+
assert.Contains(t, contentStr, `name = "production"`)
115+
})
116+
}

exporter/importables.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3365,4 +3365,12 @@ var resourcesMap map[string]importable = map[string]importable{
33653365
{Path: "alert_configurations.action_configurations.target", Resource: "databricks_user", Match: "user_name"},
33663366
},
33673367
},
3368+
"databricks_tag_policy": {
3369+
WorkspaceLevel: true,
3370+
PluginFramework: true,
3371+
Service: "uc-tags",
3372+
List: listTagPolicies,
3373+
// TODO: add import function that will emit access control rule set for the tag policy
3374+
// This requires knowing the account ID, so will be added later
3375+
},
33683376
}

0 commit comments

Comments
 (0)