Skip to content

Commit 5c38791

Browse files
authored
Integration for configuring workspace bindings (#628)
1 parent 5f6853a commit 5c38791

File tree

4 files changed

+141
-0
lines changed

4 files changed

+141
-0
lines changed

databricks_cli/unity_catalog/api.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,12 @@ def update_catalog(self, name, catalog_spec):
131131
def delete_catalog(self, catalog_name):
132132
return self.client.delete_catalog(catalog_name)
133133

134+
def get_catalog_bindings(self, name):
135+
return self.client.get_catalog_bindings(name)
136+
137+
def update_catalog_bindings(self, name, workspace_bindings_spec):
138+
return self.client.update_catalog_bindings(name, workspace_bindings_spec)
139+
134140
# Schema APIs
135141

136142
def create_schema(self, catalog_name, schema_name, comment):

databricks_cli/unity_catalog/catalog_cli.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,44 @@ def delete_catalog_cli(api_client, name, purge):
137137
UnityCatalogApi(api_client).delete_catalog(name)
138138

139139

140+
@click.command(context_settings=CONTEXT_SETTINGS,
141+
short_help='Get workspace bindings of a catalog.')
142+
@click.option('--name', required=True,
143+
help='Name of the catalog to get bindings for.')
144+
@debug_option
145+
@profile_option
146+
@eat_exceptions
147+
@provide_api_client
148+
def get_catalog_bindings_cli(api_client, name):
149+
"""
150+
Get workspace bindings of a catalog.
151+
"""
152+
catalog_json = UnityCatalogApi(api_client).get_catalog_bindings(name)
153+
click.echo(mc_pretty_format(catalog_json))
154+
155+
156+
@click.command(context_settings=CONTEXT_SETTINGS,
157+
short_help='Update workspace bindings of a catalog.')
158+
@click.option('--name', required=True,
159+
help='Name of the catalog to update bindings for.')
160+
@click.option('--json-file', default=None, type=click.Path(),
161+
help=json_file_help(method='PATCH', path='/workspace-bindings/catalogs/{name}'))
162+
@click.option('--json', default=None, type=JsonClickType(),
163+
help=json_string_help(method='PATCH', path='/workspace-bindings/catalogs/{name}'))
164+
@debug_option
165+
@profile_option
166+
@eat_exceptions
167+
@provide_api_client
168+
def update_catalog_bindings_cli(api_client, name, json_file, json):
169+
"""
170+
Update workspace bindings of a catalog.
171+
172+
The public specification for the JSON request is in development.
173+
"""
174+
json_cli_base(json_file, json,
175+
lambda json: UnityCatalogApi(api_client).update_catalog_bindings(name, json))
176+
177+
140178
@click.group()
141179
def catalogs_group(): # pragma: no cover
142180
pass
@@ -149,11 +187,15 @@ def register_catalog_commands(cmd_group):
149187
cmd_group.add_command(hide(get_catalog_cli), name='get-catalog')
150188
cmd_group.add_command(hide(update_catalog_cli), name='update-catalog')
151189
cmd_group.add_command(hide(delete_catalog_cli), name='delete-catalog')
190+
cmd_group.add_command(hide(get_catalog_bindings_cli), name='get-catalog-bindings')
191+
cmd_group.add_command(hide(update_catalog_bindings_cli), name='update-catalog-bindings')
152192

153193
# Register command group.
154194
catalogs_group.add_command(create_catalog_cli, name='create')
155195
catalogs_group.add_command(list_catalogs_cli, name='list')
156196
catalogs_group.add_command(get_catalog_cli, name='get')
157197
catalogs_group.add_command(update_catalog_cli, name='update')
158198
catalogs_group.add_command(delete_catalog_cli, name='delete')
199+
catalogs_group.add_command(get_catalog_bindings_cli, name='get-bindings')
200+
catalogs_group.add_command(update_catalog_bindings_cli, name='update-bindings')
159201
cmd_group.add_command(catalogs_group, name='catalogs')

databricks_cli/unity_catalog/uc_service.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,17 @@ def delete_catalog(self, name, headers=None):
239239
return self.client.perform_query('DELETE', '/unity-catalog/catalogs/%s' % (name),
240240
data=_data, headers=headers)
241241

242+
def get_catalog_bindings(self, name, headers=None):
243+
_data = {}
244+
return self.client.perform_query('GET',
245+
'/unity-catalog/workspace-bindings/catalogs/%s' % (name),
246+
data=_data, headers=headers)
247+
248+
def update_catalog_bindings(self, name, workspace_bindings_spec, headers=None):
249+
return self.client.perform_query('PATCH',
250+
'/unity-catalog/workspace-bindings/catalogs/%s' % (name),
251+
data=workspace_bindings_spec, headers=headers)
252+
242253
# Schema Operations
243254

244255
def create_schema(self, catalog_name, new_schema_name, comment=None, headers=None):
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Databricks CLI
2+
# Copyright 2017 Databricks, Inc.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License"), except
5+
# that the use of services to which certain application programming
6+
# interfaces (each, an "API") connect requires that the user first obtain
7+
# a license for the use of the APIs from Databricks, Inc. ("Databricks"),
8+
# by creating an account at www.databricks.com and agreeing to either (a)
9+
# the Community Edition Terms of Service, (b) the Databricks Terms of
10+
# Service, or (c) another written agreement between Licensee and Databricks
11+
# for the use of the APIs.
12+
#
13+
# You may not use this file except in compliance with the License.
14+
# You may obtain a copy of the License at
15+
#
16+
# http://www.apache.org/licenses/LICENSE-2.0
17+
#
18+
# Unless required by applicable law or agreed to in writing, software
19+
# distributed under the License is distributed on an "AS IS" BASIS,
20+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21+
# See the License for the specific language governing permissions and
22+
# limitations under the License.
23+
24+
# pylint:disable=redefined-outer-name
25+
26+
import mock
27+
import pytest
28+
from click.testing import CliRunner
29+
from databricks_cli.unity_catalog.utils import mc_pretty_format
30+
31+
from databricks_cli.unity_catalog import catalog_cli
32+
from tests.utils import provide_conf
33+
34+
CATALOG_NAME = 'test_catalog_name'
35+
36+
WORKSPACE_BINDINGS = {
37+
"workspaces": [6051921418418893]
38+
}
39+
40+
EMPTY_WORKSPACE_BINDINGS = {}
41+
42+
@pytest.fixture()
43+
def api_mock():
44+
with mock.patch(
45+
'databricks_cli.unity_catalog.catalog_cli.UnityCatalogApi') as uc_api_mock:
46+
_cred_api_mock = mock.MagicMock()
47+
uc_api_mock.return_value = _cred_api_mock
48+
yield _cred_api_mock
49+
50+
51+
@pytest.fixture()
52+
def echo_mock():
53+
with mock.patch('databricks_cli.unity_catalog.catalog_cli.click.echo') as echo_mock:
54+
yield echo_mock
55+
56+
57+
@provide_conf
58+
def test_get_catalog_bindings_cli(api_mock, echo_mock):
59+
api_mock.get_catalog_bindings.return_value = WORKSPACE_BINDINGS
60+
runner = CliRunner()
61+
runner.invoke(
62+
catalog_cli.get_catalog_bindings_cli,
63+
args=['--name', CATALOG_NAME])
64+
api_mock.get_catalog_bindings.assert_called_once()
65+
echo_mock.assert_called_once_with(mc_pretty_format(WORKSPACE_BINDINGS))
66+
67+
@provide_conf
68+
def test_update_catalog_bindings_cli_with_json(api_mock, echo_mock):
69+
api_mock.update_catalog_bindings.return_value = EMPTY_WORKSPACE_BINDINGS
70+
runner = CliRunner()
71+
runner.invoke(
72+
catalog_cli.update_catalog_bindings_cli,
73+
args=[
74+
'--name', CATALOG_NAME,
75+
'--json', '{ "unassign_workspaces": [6051921418418893] }'
76+
])
77+
api_mock.update_catalog_bindings.assert_called_once_with(
78+
CATALOG_NAME,
79+
{
80+
'unassign_workspaces': [6051921418418893]
81+
})
82+
echo_mock.assert_called_once_with(mc_pretty_format(EMPTY_WORKSPACE_BINDINGS))

0 commit comments

Comments
 (0)