Skip to content

Commit 0856b26

Browse files
authored
Exporter for Databricks SQL objects (#1199)
* initial work for SQLA exporter * working exporter for queries & sql endpoints * export of visualizations & dashboards * visualizations need to be re-implemented to play nicely with widgets
1 parent 28f3fcf commit 0856b26

19 files changed

+920
-25
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## 0.5.4
44

55
* Completely removed custom client-side validation in `databricks_service_principal` ([#1193](https://github.com/databrickslabs/terraform-provider-databricks/issues/1193)).
6+
* Added export functionality for Databricks SQL objects - endpoints, queries, dashboards, widgets, visualizations ([#1199](https://github.com/databrickslabs/terraform-provider-databricks/pull/1199)).
67

78
Updated dependency versions:
89

exporter/context.go

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,23 +47,25 @@ import (
4747
*/
4848

4949
type importContext struct {
50-
Module string
51-
Context context.Context
52-
Client *common.DatabricksClient
53-
State stateApproximation
54-
Importables map[string]importable
55-
Resources map[string]*schema.Resource
56-
Scope importedResources
57-
Files map[string]*hclwrite.File
58-
Directory string
59-
importing map[string]bool
60-
nameFixes []regexFix
61-
hclFixes []regexFix
62-
allUsers []scim.User
63-
allGroups []scim.Group
64-
mountMap map[string]mount
65-
variables map[string]string
66-
testEmits map[string]bool
50+
Module string
51+
Context context.Context
52+
Client *common.DatabricksClient
53+
State stateApproximation
54+
Importables map[string]importable
55+
Resources map[string]*schema.Resource
56+
Scope importedResources
57+
Files map[string]*hclwrite.File
58+
Directory string
59+
importing map[string]bool
60+
nameFixes []regexFix
61+
hclFixes []regexFix
62+
allUsers []scim.User
63+
allGroups []scim.Group
64+
mountMap map[string]mount
65+
variables map[string]string
66+
testEmits map[string]bool
67+
sqlDatasources map[string]string
68+
sqlVisualizations map[string]string
6769

6870
debug bool
6971
mounts bool

exporter/exporter_test.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/databrickslabs/terraform-provider-databricks/repos"
2323
"github.com/databrickslabs/terraform-provider-databricks/scim"
2424
"github.com/databrickslabs/terraform-provider-databricks/secrets"
25+
"github.com/databrickslabs/terraform-provider-databricks/sql"
2526
"github.com/databrickslabs/terraform-provider-databricks/workspace"
2627
"github.com/hashicorp/hcl/v2/hclwrite"
2728

@@ -224,6 +225,27 @@ var emptyWorkspace = qa.HTTPFixture{
224225
Response: workspace.ObjectList{},
225226
}
226227

228+
var emptySqlEndpoints = qa.HTTPFixture{
229+
Method: "GET",
230+
Resource: "/api/2.0/sql/endpoints",
231+
Response: map[string]interface{}{},
232+
ReuseRequest: true,
233+
}
234+
235+
var emptySqlDashboards = qa.HTTPFixture{
236+
Method: "GET",
237+
Resource: "/api/2.0/preview/sql/dashboards",
238+
Response: map[string]interface{}{},
239+
ReuseRequest: true,
240+
}
241+
242+
var emptySqlQueries = qa.HTTPFixture{
243+
Method: "GET",
244+
Resource: "/api/2.0/preview/sql/queries",
245+
Response: map[string]interface{}{},
246+
ReuseRequest: true,
247+
}
248+
227249
func TestImportingUsersGroupsSecretScopes(t *testing.T) {
228250
qa.HTTPFixturesApply(t,
229251
[]qa.HTTPFixture{
@@ -232,6 +254,9 @@ func TestImportingUsersGroupsSecretScopes(t *testing.T) {
232254
emptyGitCredentials,
233255
emptyWorkspace,
234256
emptyIpAccessLIst,
257+
emptySqlDashboards,
258+
emptySqlEndpoints,
259+
emptySqlQueries,
235260
{
236261
Method: "GET",
237262
Resource: "/api/2.0/preview/scim/v2/Groups?",
@@ -393,6 +418,9 @@ func TestImportingNoResourcesError(t *testing.T) {
393418
emptyGitCredentials,
394419
emptyIpAccessLIst,
395420
emptyWorkspace,
421+
emptySqlEndpoints,
422+
emptySqlQueries,
423+
emptySqlDashboards,
396424
{
397425
Method: "GET",
398426
Resource: "/api/2.0/global-init-scripts",
@@ -1068,3 +1096,89 @@ func TestImportingIPAccessLists(t *testing.T) {
10681096
assert.NoError(t, err)
10691097
})
10701098
}
1099+
1100+
func TestImportingSqlObjects(t *testing.T) {
1101+
qa.HTTPFixturesApply(t,
1102+
[]qa.HTTPFixture{
1103+
meAdminFixture,
1104+
emptyRepos,
1105+
emptyIpAccessLIst,
1106+
{
1107+
Method: "GET",
1108+
Resource: "/api/2.0/global-init-scripts",
1109+
Response: map[string]interface{}{},
1110+
},
1111+
{
1112+
Method: "GET",
1113+
Resource: "/api/2.0/sql/endpoints",
1114+
Response: getJSONObject("test-data/get-sql-endpoints.json"),
1115+
},
1116+
{
1117+
Method: "GET",
1118+
Resource: "/api/2.0/sql/endpoints/f562046bc1272886",
1119+
Response: getJSONObject("test-data/get-sql-endpoint.json"),
1120+
},
1121+
{
1122+
Method: "GET",
1123+
Resource: "/api/2.0/preview/sql/data_sources",
1124+
Response: []sql.DataSource{
1125+
{
1126+
ID: "147164a6-8316-4a9d-beff-f57261801374",
1127+
EndpointID: "f562046bc1272886",
1128+
},
1129+
},
1130+
ReuseRequest: true,
1131+
},
1132+
{
1133+
Method: "GET",
1134+
Resource: "/api/2.0/permissions/sql/endpoints/f562046bc1272886",
1135+
Response: getJSONObject("test-data/get-sql-endpoint-permissions.json"),
1136+
},
1137+
{
1138+
Method: "GET",
1139+
Resource: "/api/2.0/preview/sql/dashboards",
1140+
Response: getJSONObject("test-data/get-sql-dashboards.json"),
1141+
ReuseRequest: true,
1142+
},
1143+
{
1144+
Method: "GET",
1145+
Resource: "/api/2.0/preview/sql/dashboards/9cb0c8f5-6262-4a1f-a741-2181de76028f",
1146+
Response: getJSONObject("test-data/get-sql-dashboard.json"),
1147+
ReuseRequest: true,
1148+
},
1149+
{
1150+
Method: "GET",
1151+
Resource: "/api/2.0/preview/sql/queries",
1152+
Response: getJSONObject("test-data/get-sql-queries.json"),
1153+
ReuseRequest: true,
1154+
},
1155+
{
1156+
Method: "GET",
1157+
Resource: "/api/2.0/preview/sql/queries/16c4f969-eea0-4aad-8f82-03d79b078dcc",
1158+
Response: getJSONObject("test-data/get-sql-query.json"),
1159+
ReuseRequest: true,
1160+
},
1161+
{
1162+
Method: "GET",
1163+
Resource: "/api/2.0/preview/sql/permissions/queries/16c4f969-eea0-4aad-8f82-03d79b078dcc",
1164+
Response: getJSONObject("test-data/get-sql-query-permissions.json"),
1165+
},
1166+
{
1167+
Method: "GET",
1168+
Resource: "/api/2.0/preview/sql/permissions/dashboards/9cb0c8f5-6262-4a1f-a741-2181de76028f",
1169+
Response: getJSONObject("test-data/get-sql-dashboard-permissions.json"),
1170+
},
1171+
},
1172+
func(ctx context.Context, client *common.DatabricksClient) {
1173+
tmpDir := fmt.Sprintf("/tmp/tf-%s", qa.RandomName())
1174+
defer os.RemoveAll(tmpDir)
1175+
1176+
ic := newImportContext(client)
1177+
ic.Directory = tmpDir
1178+
ic.listing = "sql,access"
1179+
ic.services = "sql,access"
1180+
1181+
err := ic.Run()
1182+
assert.NoError(t, err)
1183+
})
1184+
}

0 commit comments

Comments
 (0)