databricks-sdk 0.36.0__py3-none-any.whl → 0.38.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of databricks-sdk might be problematic. Click here for more details.
- databricks/sdk/__init__.py +22 -29
- databricks/sdk/_base_client.py +61 -14
- databricks/sdk/config.py +10 -9
- databricks/sdk/credentials_provider.py +6 -5
- databricks/sdk/mixins/jobs.py +49 -0
- databricks/sdk/service/apps.py +50 -186
- databricks/sdk/service/billing.py +1 -1
- databricks/sdk/service/catalog.py +952 -45
- databricks/sdk/service/compute.py +23 -20
- databricks/sdk/service/dashboards.py +31 -281
- databricks/sdk/service/iam.py +6 -4
- databricks/sdk/service/jobs.py +93 -76
- databricks/sdk/service/marketplace.py +1 -0
- databricks/sdk/service/ml.py +4 -3
- databricks/sdk/service/oauth2.py +29 -8
- databricks/sdk/service/pipelines.py +94 -20
- databricks/sdk/service/provisioning.py +68 -0
- databricks/sdk/service/serving.py +2 -2
- databricks/sdk/service/settings.py +322 -2
- databricks/sdk/service/sharing.py +2 -618
- databricks/sdk/service/sql.py +7 -7
- databricks/sdk/service/workspace.py +7 -4
- databricks/sdk/version.py +1 -1
- {databricks_sdk-0.36.0.dist-info → databricks_sdk-0.38.0.dist-info}/METADATA +1 -1
- {databricks_sdk-0.36.0.dist-info → databricks_sdk-0.38.0.dist-info}/RECORD +29 -28
- {databricks_sdk-0.36.0.dist-info → databricks_sdk-0.38.0.dist-info}/WHEEL +1 -1
- {databricks_sdk-0.36.0.dist-info → databricks_sdk-0.38.0.dist-info}/LICENSE +0 -0
- {databricks_sdk-0.36.0.dist-info → databricks_sdk-0.38.0.dist-info}/NOTICE +0 -0
- {databricks_sdk-0.36.0.dist-info → databricks_sdk-0.38.0.dist-info}/top_level.txt +0 -0
|
@@ -3,11 +3,15 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import logging
|
|
6
|
+
import random
|
|
7
|
+
import time
|
|
6
8
|
from dataclasses import dataclass
|
|
9
|
+
from datetime import timedelta
|
|
7
10
|
from enum import Enum
|
|
8
|
-
from typing import Dict, Iterator, List, Optional
|
|
11
|
+
from typing import Callable, Dict, Iterator, List, Optional
|
|
9
12
|
|
|
10
|
-
from
|
|
13
|
+
from ..errors import OperationFailed
|
|
14
|
+
from ._internal import Wait, _enum, _from_dict, _repeated_dict, _repeated_enum
|
|
11
15
|
|
|
12
16
|
_LOG = logging.getLogger('databricks.sdk')
|
|
13
17
|
|
|
@@ -310,6 +314,36 @@ class AwsCredentials:
|
|
|
310
314
|
session_token=d.get('session_token', None))
|
|
311
315
|
|
|
312
316
|
|
|
317
|
+
@dataclass
|
|
318
|
+
class AwsIamRole:
|
|
319
|
+
"""The AWS IAM role configuration"""
|
|
320
|
+
|
|
321
|
+
external_id: Optional[str] = None
|
|
322
|
+
"""The external ID used in role assumption to prevent the confused deputy problem."""
|
|
323
|
+
|
|
324
|
+
role_arn: Optional[str] = None
|
|
325
|
+
"""The Amazon Resource Name (ARN) of the AWS IAM role used to vend temporary credentials."""
|
|
326
|
+
|
|
327
|
+
unity_catalog_iam_arn: Optional[str] = None
|
|
328
|
+
"""The Amazon Resource Name (ARN) of the AWS IAM user managed by Databricks. This is the identity
|
|
329
|
+
that is going to assume the AWS IAM role."""
|
|
330
|
+
|
|
331
|
+
def as_dict(self) -> dict:
|
|
332
|
+
"""Serializes the AwsIamRole into a dictionary suitable for use as a JSON request body."""
|
|
333
|
+
body = {}
|
|
334
|
+
if self.external_id is not None: body['external_id'] = self.external_id
|
|
335
|
+
if self.role_arn is not None: body['role_arn'] = self.role_arn
|
|
336
|
+
if self.unity_catalog_iam_arn is not None: body['unity_catalog_iam_arn'] = self.unity_catalog_iam_arn
|
|
337
|
+
return body
|
|
338
|
+
|
|
339
|
+
@classmethod
|
|
340
|
+
def from_dict(cls, d: Dict[str, any]) -> AwsIamRole:
|
|
341
|
+
"""Deserializes the AwsIamRole from a dictionary."""
|
|
342
|
+
return cls(external_id=d.get('external_id', None),
|
|
343
|
+
role_arn=d.get('role_arn', None),
|
|
344
|
+
unity_catalog_iam_arn=d.get('unity_catalog_iam_arn', None))
|
|
345
|
+
|
|
346
|
+
|
|
313
347
|
@dataclass
|
|
314
348
|
class AwsIamRoleRequest:
|
|
315
349
|
role_arn: str
|
|
@@ -355,6 +389,64 @@ class AwsIamRoleResponse:
|
|
|
355
389
|
unity_catalog_iam_arn=d.get('unity_catalog_iam_arn', None))
|
|
356
390
|
|
|
357
391
|
|
|
392
|
+
@dataclass
|
|
393
|
+
class AzureActiveDirectoryToken:
|
|
394
|
+
"""Azure Active Directory token, essentially the Oauth token for Azure Service Principal or Managed
|
|
395
|
+
Identity. Read more at
|
|
396
|
+
https://learn.microsoft.com/en-us/azure/databricks/dev-tools/api/latest/aad/service-prin-aad-token"""
|
|
397
|
+
|
|
398
|
+
aad_token: Optional[str] = None
|
|
399
|
+
"""Opaque token that contains claims that you can use in Azure Active Directory to access cloud
|
|
400
|
+
services."""
|
|
401
|
+
|
|
402
|
+
def as_dict(self) -> dict:
|
|
403
|
+
"""Serializes the AzureActiveDirectoryToken into a dictionary suitable for use as a JSON request body."""
|
|
404
|
+
body = {}
|
|
405
|
+
if self.aad_token is not None: body['aad_token'] = self.aad_token
|
|
406
|
+
return body
|
|
407
|
+
|
|
408
|
+
@classmethod
|
|
409
|
+
def from_dict(cls, d: Dict[str, any]) -> AzureActiveDirectoryToken:
|
|
410
|
+
"""Deserializes the AzureActiveDirectoryToken from a dictionary."""
|
|
411
|
+
return cls(aad_token=d.get('aad_token', None))
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
@dataclass
|
|
415
|
+
class AzureManagedIdentity:
|
|
416
|
+
"""The Azure managed identity configuration."""
|
|
417
|
+
|
|
418
|
+
access_connector_id: str
|
|
419
|
+
"""The Azure resource ID of the Azure Databricks Access Connector. Use the format
|
|
420
|
+
`/subscriptions/{guid}/resourceGroups/{rg-name}/providers/Microsoft.Databricks/accessConnectors/{connector-name}`."""
|
|
421
|
+
|
|
422
|
+
credential_id: Optional[str] = None
|
|
423
|
+
"""The Databricks internal ID that represents this managed identity. This field is only used to
|
|
424
|
+
persist the credential_id once it is fetched from the credentials manager - as we only use the
|
|
425
|
+
protobuf serializer to store credentials, this ID gets persisted to the database. ."""
|
|
426
|
+
|
|
427
|
+
managed_identity_id: Optional[str] = None
|
|
428
|
+
"""The Azure resource ID of the managed identity. Use the format,
|
|
429
|
+
`/subscriptions/{guid}/resourceGroups/{rg-name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identity-name}`
|
|
430
|
+
This is only available for user-assgined identities. For system-assigned identities, the
|
|
431
|
+
access_connector_id is used to identify the identity. If this field is not provided, then we
|
|
432
|
+
assume the AzureManagedIdentity is using the system-assigned identity."""
|
|
433
|
+
|
|
434
|
+
def as_dict(self) -> dict:
|
|
435
|
+
"""Serializes the AzureManagedIdentity into a dictionary suitable for use as a JSON request body."""
|
|
436
|
+
body = {}
|
|
437
|
+
if self.access_connector_id is not None: body['access_connector_id'] = self.access_connector_id
|
|
438
|
+
if self.credential_id is not None: body['credential_id'] = self.credential_id
|
|
439
|
+
if self.managed_identity_id is not None: body['managed_identity_id'] = self.managed_identity_id
|
|
440
|
+
return body
|
|
441
|
+
|
|
442
|
+
@classmethod
|
|
443
|
+
def from_dict(cls, d: Dict[str, any]) -> AzureManagedIdentity:
|
|
444
|
+
"""Deserializes the AzureManagedIdentity from a dictionary."""
|
|
445
|
+
return cls(access_connector_id=d.get('access_connector_id', None),
|
|
446
|
+
credential_id=d.get('credential_id', None),
|
|
447
|
+
managed_identity_id=d.get('managed_identity_id', None))
|
|
448
|
+
|
|
449
|
+
|
|
358
450
|
@dataclass
|
|
359
451
|
class AzureManagedIdentityRequest:
|
|
360
452
|
access_connector_id: str
|
|
@@ -416,6 +508,8 @@ class AzureManagedIdentityResponse:
|
|
|
416
508
|
|
|
417
509
|
@dataclass
|
|
418
510
|
class AzureServicePrincipal:
|
|
511
|
+
"""The Azure service principal configuration."""
|
|
512
|
+
|
|
419
513
|
directory_id: str
|
|
420
514
|
"""The directory ID corresponding to the Azure Active Directory (AAD) tenant of the application."""
|
|
421
515
|
|
|
@@ -793,6 +887,7 @@ class ColumnTypeName(Enum):
|
|
|
793
887
|
TIMESTAMP = 'TIMESTAMP'
|
|
794
888
|
TIMESTAMP_NTZ = 'TIMESTAMP_NTZ'
|
|
795
889
|
USER_DEFINED_TYPE = 'USER_DEFINED_TYPE'
|
|
890
|
+
VARIANT = 'VARIANT'
|
|
796
891
|
|
|
797
892
|
|
|
798
893
|
@dataclass
|
|
@@ -1066,6 +1161,66 @@ class CreateConnection:
|
|
|
1066
1161
|
read_only=d.get('read_only', None))
|
|
1067
1162
|
|
|
1068
1163
|
|
|
1164
|
+
@dataclass
|
|
1165
|
+
class CreateCredentialRequest:
|
|
1166
|
+
name: str
|
|
1167
|
+
"""The credential name. The name must be unique among storage and service credentials within the
|
|
1168
|
+
metastore."""
|
|
1169
|
+
|
|
1170
|
+
aws_iam_role: Optional[AwsIamRole] = None
|
|
1171
|
+
"""The AWS IAM role configuration"""
|
|
1172
|
+
|
|
1173
|
+
azure_managed_identity: Optional[AzureManagedIdentity] = None
|
|
1174
|
+
"""The Azure managed identity configuration."""
|
|
1175
|
+
|
|
1176
|
+
azure_service_principal: Optional[AzureServicePrincipal] = None
|
|
1177
|
+
"""The Azure service principal configuration."""
|
|
1178
|
+
|
|
1179
|
+
comment: Optional[str] = None
|
|
1180
|
+
"""Comment associated with the credential."""
|
|
1181
|
+
|
|
1182
|
+
gcp_service_account_key: Optional[GcpServiceAccountKey] = None
|
|
1183
|
+
|
|
1184
|
+
purpose: Optional[CredentialPurpose] = None
|
|
1185
|
+
"""Indicates the purpose of the credential."""
|
|
1186
|
+
|
|
1187
|
+
read_only: Optional[bool] = None
|
|
1188
|
+
"""Whether the credential is usable only for read operations. Only applicable when purpose is
|
|
1189
|
+
**STORAGE**."""
|
|
1190
|
+
|
|
1191
|
+
skip_validation: Optional[bool] = None
|
|
1192
|
+
"""Optional. Supplying true to this argument skips validation of the created set of credentials."""
|
|
1193
|
+
|
|
1194
|
+
def as_dict(self) -> dict:
|
|
1195
|
+
"""Serializes the CreateCredentialRequest into a dictionary suitable for use as a JSON request body."""
|
|
1196
|
+
body = {}
|
|
1197
|
+
if self.aws_iam_role: body['aws_iam_role'] = self.aws_iam_role.as_dict()
|
|
1198
|
+
if self.azure_managed_identity: body['azure_managed_identity'] = self.azure_managed_identity.as_dict()
|
|
1199
|
+
if self.azure_service_principal:
|
|
1200
|
+
body['azure_service_principal'] = self.azure_service_principal.as_dict()
|
|
1201
|
+
if self.comment is not None: body['comment'] = self.comment
|
|
1202
|
+
if self.gcp_service_account_key:
|
|
1203
|
+
body['gcp_service_account_key'] = self.gcp_service_account_key.as_dict()
|
|
1204
|
+
if self.name is not None: body['name'] = self.name
|
|
1205
|
+
if self.purpose is not None: body['purpose'] = self.purpose.value
|
|
1206
|
+
if self.read_only is not None: body['read_only'] = self.read_only
|
|
1207
|
+
if self.skip_validation is not None: body['skip_validation'] = self.skip_validation
|
|
1208
|
+
return body
|
|
1209
|
+
|
|
1210
|
+
@classmethod
|
|
1211
|
+
def from_dict(cls, d: Dict[str, any]) -> CreateCredentialRequest:
|
|
1212
|
+
"""Deserializes the CreateCredentialRequest from a dictionary."""
|
|
1213
|
+
return cls(aws_iam_role=_from_dict(d, 'aws_iam_role', AwsIamRole),
|
|
1214
|
+
azure_managed_identity=_from_dict(d, 'azure_managed_identity', AzureManagedIdentity),
|
|
1215
|
+
azure_service_principal=_from_dict(d, 'azure_service_principal', AzureServicePrincipal),
|
|
1216
|
+
comment=d.get('comment', None),
|
|
1217
|
+
gcp_service_account_key=_from_dict(d, 'gcp_service_account_key', GcpServiceAccountKey),
|
|
1218
|
+
name=d.get('name', None),
|
|
1219
|
+
purpose=_enum(d, 'purpose', CredentialPurpose),
|
|
1220
|
+
read_only=d.get('read_only', None),
|
|
1221
|
+
skip_validation=d.get('skip_validation', None))
|
|
1222
|
+
|
|
1223
|
+
|
|
1069
1224
|
@dataclass
|
|
1070
1225
|
class CreateExternalLocation:
|
|
1071
1226
|
name: str
|
|
@@ -1278,7 +1433,7 @@ class CreateFunctionRoutineBody(Enum):
|
|
|
1278
1433
|
|
|
1279
1434
|
|
|
1280
1435
|
class CreateFunctionSecurityType(Enum):
|
|
1281
|
-
"""
|
|
1436
|
+
"""The security type of the function."""
|
|
1282
1437
|
|
|
1283
1438
|
DEFINER = 'DEFINER'
|
|
1284
1439
|
|
|
@@ -1439,29 +1594,6 @@ class CreateMonitor:
|
|
|
1439
1594
|
warehouse_id=d.get('warehouse_id', None))
|
|
1440
1595
|
|
|
1441
1596
|
|
|
1442
|
-
@dataclass
|
|
1443
|
-
class CreateOnlineTableRequest:
|
|
1444
|
-
"""Online Table information."""
|
|
1445
|
-
|
|
1446
|
-
name: Optional[str] = None
|
|
1447
|
-
"""Full three-part (catalog, schema, table) name of the table."""
|
|
1448
|
-
|
|
1449
|
-
spec: Optional[OnlineTableSpec] = None
|
|
1450
|
-
"""Specification of the online table."""
|
|
1451
|
-
|
|
1452
|
-
def as_dict(self) -> dict:
|
|
1453
|
-
"""Serializes the CreateOnlineTableRequest into a dictionary suitable for use as a JSON request body."""
|
|
1454
|
-
body = {}
|
|
1455
|
-
if self.name is not None: body['name'] = self.name
|
|
1456
|
-
if self.spec: body['spec'] = self.spec.as_dict()
|
|
1457
|
-
return body
|
|
1458
|
-
|
|
1459
|
-
@classmethod
|
|
1460
|
-
def from_dict(cls, d: Dict[str, any]) -> CreateOnlineTableRequest:
|
|
1461
|
-
"""Deserializes the CreateOnlineTableRequest from a dictionary."""
|
|
1462
|
-
return cls(name=d.get('name', None), spec=_from_dict(d, 'spec', OnlineTableSpec))
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
1597
|
@dataclass
|
|
1466
1598
|
class CreateRegisteredModelRequest:
|
|
1467
1599
|
catalog_name: str
|
|
@@ -1675,6 +1807,114 @@ class CreateVolumeRequestContent:
|
|
|
1675
1807
|
volume_type=_enum(d, 'volume_type', VolumeType))
|
|
1676
1808
|
|
|
1677
1809
|
|
|
1810
|
+
@dataclass
|
|
1811
|
+
class CredentialInfo:
|
|
1812
|
+
aws_iam_role: Optional[AwsIamRole] = None
|
|
1813
|
+
"""The AWS IAM role configuration"""
|
|
1814
|
+
|
|
1815
|
+
azure_managed_identity: Optional[AzureManagedIdentity] = None
|
|
1816
|
+
"""The Azure managed identity configuration."""
|
|
1817
|
+
|
|
1818
|
+
azure_service_principal: Optional[AzureServicePrincipal] = None
|
|
1819
|
+
"""The Azure service principal configuration."""
|
|
1820
|
+
|
|
1821
|
+
comment: Optional[str] = None
|
|
1822
|
+
"""Comment associated with the credential."""
|
|
1823
|
+
|
|
1824
|
+
created_at: Optional[int] = None
|
|
1825
|
+
"""Time at which this credential was created, in epoch milliseconds."""
|
|
1826
|
+
|
|
1827
|
+
created_by: Optional[str] = None
|
|
1828
|
+
"""Username of credential creator."""
|
|
1829
|
+
|
|
1830
|
+
full_name: Optional[str] = None
|
|
1831
|
+
"""The full name of the credential."""
|
|
1832
|
+
|
|
1833
|
+
id: Optional[str] = None
|
|
1834
|
+
"""The unique identifier of the credential."""
|
|
1835
|
+
|
|
1836
|
+
isolation_mode: Optional[IsolationMode] = None
|
|
1837
|
+
"""Whether the current securable is accessible from all workspaces or a specific set of workspaces."""
|
|
1838
|
+
|
|
1839
|
+
metastore_id: Optional[str] = None
|
|
1840
|
+
"""Unique identifier of the parent metastore."""
|
|
1841
|
+
|
|
1842
|
+
name: Optional[str] = None
|
|
1843
|
+
"""The credential name. The name must be unique among storage and service credentials within the
|
|
1844
|
+
metastore."""
|
|
1845
|
+
|
|
1846
|
+
owner: Optional[str] = None
|
|
1847
|
+
"""Username of current owner of credential."""
|
|
1848
|
+
|
|
1849
|
+
purpose: Optional[CredentialPurpose] = None
|
|
1850
|
+
"""Indicates the purpose of the credential."""
|
|
1851
|
+
|
|
1852
|
+
read_only: Optional[bool] = None
|
|
1853
|
+
"""Whether the credential is usable only for read operations. Only applicable when purpose is
|
|
1854
|
+
**STORAGE**."""
|
|
1855
|
+
|
|
1856
|
+
updated_at: Optional[int] = None
|
|
1857
|
+
"""Time at which this credential was last modified, in epoch milliseconds."""
|
|
1858
|
+
|
|
1859
|
+
updated_by: Optional[str] = None
|
|
1860
|
+
"""Username of user who last modified the credential."""
|
|
1861
|
+
|
|
1862
|
+
used_for_managed_storage: Optional[bool] = None
|
|
1863
|
+
"""Whether this credential is the current metastore's root storage credential. Only applicable when
|
|
1864
|
+
purpose is **STORAGE**."""
|
|
1865
|
+
|
|
1866
|
+
def as_dict(self) -> dict:
|
|
1867
|
+
"""Serializes the CredentialInfo into a dictionary suitable for use as a JSON request body."""
|
|
1868
|
+
body = {}
|
|
1869
|
+
if self.aws_iam_role: body['aws_iam_role'] = self.aws_iam_role.as_dict()
|
|
1870
|
+
if self.azure_managed_identity: body['azure_managed_identity'] = self.azure_managed_identity.as_dict()
|
|
1871
|
+
if self.azure_service_principal:
|
|
1872
|
+
body['azure_service_principal'] = self.azure_service_principal.as_dict()
|
|
1873
|
+
if self.comment is not None: body['comment'] = self.comment
|
|
1874
|
+
if self.created_at is not None: body['created_at'] = self.created_at
|
|
1875
|
+
if self.created_by is not None: body['created_by'] = self.created_by
|
|
1876
|
+
if self.full_name is not None: body['full_name'] = self.full_name
|
|
1877
|
+
if self.id is not None: body['id'] = self.id
|
|
1878
|
+
if self.isolation_mode is not None: body['isolation_mode'] = self.isolation_mode.value
|
|
1879
|
+
if self.metastore_id is not None: body['metastore_id'] = self.metastore_id
|
|
1880
|
+
if self.name is not None: body['name'] = self.name
|
|
1881
|
+
if self.owner is not None: body['owner'] = self.owner
|
|
1882
|
+
if self.purpose is not None: body['purpose'] = self.purpose.value
|
|
1883
|
+
if self.read_only is not None: body['read_only'] = self.read_only
|
|
1884
|
+
if self.updated_at is not None: body['updated_at'] = self.updated_at
|
|
1885
|
+
if self.updated_by is not None: body['updated_by'] = self.updated_by
|
|
1886
|
+
if self.used_for_managed_storage is not None:
|
|
1887
|
+
body['used_for_managed_storage'] = self.used_for_managed_storage
|
|
1888
|
+
return body
|
|
1889
|
+
|
|
1890
|
+
@classmethod
|
|
1891
|
+
def from_dict(cls, d: Dict[str, any]) -> CredentialInfo:
|
|
1892
|
+
"""Deserializes the CredentialInfo from a dictionary."""
|
|
1893
|
+
return cls(aws_iam_role=_from_dict(d, 'aws_iam_role', AwsIamRole),
|
|
1894
|
+
azure_managed_identity=_from_dict(d, 'azure_managed_identity', AzureManagedIdentity),
|
|
1895
|
+
azure_service_principal=_from_dict(d, 'azure_service_principal', AzureServicePrincipal),
|
|
1896
|
+
comment=d.get('comment', None),
|
|
1897
|
+
created_at=d.get('created_at', None),
|
|
1898
|
+
created_by=d.get('created_by', None),
|
|
1899
|
+
full_name=d.get('full_name', None),
|
|
1900
|
+
id=d.get('id', None),
|
|
1901
|
+
isolation_mode=_enum(d, 'isolation_mode', IsolationMode),
|
|
1902
|
+
metastore_id=d.get('metastore_id', None),
|
|
1903
|
+
name=d.get('name', None),
|
|
1904
|
+
owner=d.get('owner', None),
|
|
1905
|
+
purpose=_enum(d, 'purpose', CredentialPurpose),
|
|
1906
|
+
read_only=d.get('read_only', None),
|
|
1907
|
+
updated_at=d.get('updated_at', None),
|
|
1908
|
+
updated_by=d.get('updated_by', None),
|
|
1909
|
+
used_for_managed_storage=d.get('used_for_managed_storage', None))
|
|
1910
|
+
|
|
1911
|
+
|
|
1912
|
+
class CredentialPurpose(Enum):
|
|
1913
|
+
|
|
1914
|
+
SERVICE = 'SERVICE'
|
|
1915
|
+
STORAGE = 'STORAGE'
|
|
1916
|
+
|
|
1917
|
+
|
|
1678
1918
|
class CredentialType(Enum):
|
|
1679
1919
|
"""The type of credential."""
|
|
1680
1920
|
|
|
@@ -1682,6 +1922,27 @@ class CredentialType(Enum):
|
|
|
1682
1922
|
USERNAME_PASSWORD = 'USERNAME_PASSWORD'
|
|
1683
1923
|
|
|
1684
1924
|
|
|
1925
|
+
@dataclass
|
|
1926
|
+
class CredentialValidationResult:
|
|
1927
|
+
message: Optional[str] = None
|
|
1928
|
+
"""Error message would exist when the result does not equal to **PASS**."""
|
|
1929
|
+
|
|
1930
|
+
result: Optional[ValidateCredentialResult] = None
|
|
1931
|
+
"""The results of the tested operation."""
|
|
1932
|
+
|
|
1933
|
+
def as_dict(self) -> dict:
|
|
1934
|
+
"""Serializes the CredentialValidationResult into a dictionary suitable for use as a JSON request body."""
|
|
1935
|
+
body = {}
|
|
1936
|
+
if self.message is not None: body['message'] = self.message
|
|
1937
|
+
if self.result is not None: body['result'] = self.result.value
|
|
1938
|
+
return body
|
|
1939
|
+
|
|
1940
|
+
@classmethod
|
|
1941
|
+
def from_dict(cls, d: Dict[str, any]) -> CredentialValidationResult:
|
|
1942
|
+
"""Deserializes the CredentialValidationResult from a dictionary."""
|
|
1943
|
+
return cls(message=d.get('message', None), result=_enum(d, 'result', ValidateCredentialResult))
|
|
1944
|
+
|
|
1945
|
+
|
|
1685
1946
|
@dataclass
|
|
1686
1947
|
class CurrentWorkspaceBindings:
|
|
1687
1948
|
"""Currently assigned workspaces"""
|
|
@@ -1778,6 +2039,20 @@ class DeleteAliasResponse:
|
|
|
1778
2039
|
return cls()
|
|
1779
2040
|
|
|
1780
2041
|
|
|
2042
|
+
@dataclass
|
|
2043
|
+
class DeleteCredentialResponse:
|
|
2044
|
+
|
|
2045
|
+
def as_dict(self) -> dict:
|
|
2046
|
+
"""Serializes the DeleteCredentialResponse into a dictionary suitable for use as a JSON request body."""
|
|
2047
|
+
body = {}
|
|
2048
|
+
return body
|
|
2049
|
+
|
|
2050
|
+
@classmethod
|
|
2051
|
+
def from_dict(cls, d: Dict[str, any]) -> DeleteCredentialResponse:
|
|
2052
|
+
"""Deserializes the DeleteCredentialResponse from a dictionary."""
|
|
2053
|
+
return cls()
|
|
2054
|
+
|
|
2055
|
+
|
|
1781
2056
|
@dataclass
|
|
1782
2057
|
class DeleteResponse:
|
|
1783
2058
|
|
|
@@ -2052,7 +2327,6 @@ class ExternalLocationInfo:
|
|
|
2052
2327
|
sufficient."""
|
|
2053
2328
|
|
|
2054
2329
|
isolation_mode: Optional[IsolationMode] = None
|
|
2055
|
-
"""Whether the current securable is accessible from all workspaces or a specific set of workspaces."""
|
|
2056
2330
|
|
|
2057
2331
|
metastore_id: Optional[str] = None
|
|
2058
2332
|
"""Unique identifier of metastore hosting the external location."""
|
|
@@ -2382,7 +2656,7 @@ class FunctionInfoRoutineBody(Enum):
|
|
|
2382
2656
|
|
|
2383
2657
|
|
|
2384
2658
|
class FunctionInfoSecurityType(Enum):
|
|
2385
|
-
"""
|
|
2659
|
+
"""The security type of the function."""
|
|
2386
2660
|
|
|
2387
2661
|
DEFINER = 'DEFINER'
|
|
2388
2662
|
|
|
@@ -2516,6 +2790,79 @@ class GcpOauthToken:
|
|
|
2516
2790
|
return cls(oauth_token=d.get('oauth_token', None))
|
|
2517
2791
|
|
|
2518
2792
|
|
|
2793
|
+
@dataclass
|
|
2794
|
+
class GcpServiceAccountKey:
|
|
2795
|
+
"""GCP long-lived credential. GCP Service Account."""
|
|
2796
|
+
|
|
2797
|
+
email: Optional[str] = None
|
|
2798
|
+
"""The email of the service account."""
|
|
2799
|
+
|
|
2800
|
+
private_key: Optional[str] = None
|
|
2801
|
+
"""The service account's RSA private key."""
|
|
2802
|
+
|
|
2803
|
+
private_key_id: Optional[str] = None
|
|
2804
|
+
"""The ID of the service account's private key."""
|
|
2805
|
+
|
|
2806
|
+
def as_dict(self) -> dict:
|
|
2807
|
+
"""Serializes the GcpServiceAccountKey into a dictionary suitable for use as a JSON request body."""
|
|
2808
|
+
body = {}
|
|
2809
|
+
if self.email is not None: body['email'] = self.email
|
|
2810
|
+
if self.private_key is not None: body['private_key'] = self.private_key
|
|
2811
|
+
if self.private_key_id is not None: body['private_key_id'] = self.private_key_id
|
|
2812
|
+
return body
|
|
2813
|
+
|
|
2814
|
+
@classmethod
|
|
2815
|
+
def from_dict(cls, d: Dict[str, any]) -> GcpServiceAccountKey:
|
|
2816
|
+
"""Deserializes the GcpServiceAccountKey from a dictionary."""
|
|
2817
|
+
return cls(email=d.get('email', None),
|
|
2818
|
+
private_key=d.get('private_key', None),
|
|
2819
|
+
private_key_id=d.get('private_key_id', None))
|
|
2820
|
+
|
|
2821
|
+
|
|
2822
|
+
@dataclass
|
|
2823
|
+
class GenerateTemporaryServiceCredentialAzureOptions:
|
|
2824
|
+
"""Options to customize the requested temporary credential"""
|
|
2825
|
+
|
|
2826
|
+
resources: Optional[List[str]] = None
|
|
2827
|
+
"""The resources to which the temporary Azure credential should apply. These resources are the
|
|
2828
|
+
scopes that are passed to the token provider (see
|
|
2829
|
+
https://learn.microsoft.com/python/api/azure-core/azure.core.credentials.tokencredential?view=azure-python)"""
|
|
2830
|
+
|
|
2831
|
+
def as_dict(self) -> dict:
|
|
2832
|
+
"""Serializes the GenerateTemporaryServiceCredentialAzureOptions into a dictionary suitable for use as a JSON request body."""
|
|
2833
|
+
body = {}
|
|
2834
|
+
if self.resources: body['resources'] = [v for v in self.resources]
|
|
2835
|
+
return body
|
|
2836
|
+
|
|
2837
|
+
@classmethod
|
|
2838
|
+
def from_dict(cls, d: Dict[str, any]) -> GenerateTemporaryServiceCredentialAzureOptions:
|
|
2839
|
+
"""Deserializes the GenerateTemporaryServiceCredentialAzureOptions from a dictionary."""
|
|
2840
|
+
return cls(resources=d.get('resources', None))
|
|
2841
|
+
|
|
2842
|
+
|
|
2843
|
+
@dataclass
|
|
2844
|
+
class GenerateTemporaryServiceCredentialRequest:
|
|
2845
|
+
credential_name: str
|
|
2846
|
+
"""The name of the service credential used to generate a temporary credential"""
|
|
2847
|
+
|
|
2848
|
+
azure_options: Optional[GenerateTemporaryServiceCredentialAzureOptions] = None
|
|
2849
|
+
"""Options to customize the requested temporary credential"""
|
|
2850
|
+
|
|
2851
|
+
def as_dict(self) -> dict:
|
|
2852
|
+
"""Serializes the GenerateTemporaryServiceCredentialRequest into a dictionary suitable for use as a JSON request body."""
|
|
2853
|
+
body = {}
|
|
2854
|
+
if self.azure_options: body['azure_options'] = self.azure_options.as_dict()
|
|
2855
|
+
if self.credential_name is not None: body['credential_name'] = self.credential_name
|
|
2856
|
+
return body
|
|
2857
|
+
|
|
2858
|
+
@classmethod
|
|
2859
|
+
def from_dict(cls, d: Dict[str, any]) -> GenerateTemporaryServiceCredentialRequest:
|
|
2860
|
+
"""Deserializes the GenerateTemporaryServiceCredentialRequest from a dictionary."""
|
|
2861
|
+
return cls(azure_options=_from_dict(d, 'azure_options',
|
|
2862
|
+
GenerateTemporaryServiceCredentialAzureOptions),
|
|
2863
|
+
credential_name=d.get('credential_name', None))
|
|
2864
|
+
|
|
2865
|
+
|
|
2519
2866
|
@dataclass
|
|
2520
2867
|
class GenerateTemporaryTableCredentialRequest:
|
|
2521
2868
|
operation: Optional[TableOperation] = None
|
|
@@ -2545,6 +2892,11 @@ class GenerateTemporaryTableCredentialResponse:
|
|
|
2545
2892
|
"""AWS temporary credentials for API authentication. Read more at
|
|
2546
2893
|
https://docs.aws.amazon.com/STS/latest/APIReference/API_Credentials.html."""
|
|
2547
2894
|
|
|
2895
|
+
azure_aad: Optional[AzureActiveDirectoryToken] = None
|
|
2896
|
+
"""Azure Active Directory token, essentially the Oauth token for Azure Service Principal or Managed
|
|
2897
|
+
Identity. Read more at
|
|
2898
|
+
https://learn.microsoft.com/en-us/azure/databricks/dev-tools/api/latest/aad/service-prin-aad-token"""
|
|
2899
|
+
|
|
2548
2900
|
azure_user_delegation_sas: Optional[AzureUserDelegationSas] = None
|
|
2549
2901
|
"""Azure temporary credentials for API authentication. Read more at
|
|
2550
2902
|
https://docs.microsoft.com/en-us/rest/api/storageservices/create-user-delegation-sas"""
|
|
@@ -2568,6 +2920,7 @@ class GenerateTemporaryTableCredentialResponse:
|
|
|
2568
2920
|
"""Serializes the GenerateTemporaryTableCredentialResponse into a dictionary suitable for use as a JSON request body."""
|
|
2569
2921
|
body = {}
|
|
2570
2922
|
if self.aws_temp_credentials: body['aws_temp_credentials'] = self.aws_temp_credentials.as_dict()
|
|
2923
|
+
if self.azure_aad: body['azure_aad'] = self.azure_aad.as_dict()
|
|
2571
2924
|
if self.azure_user_delegation_sas:
|
|
2572
2925
|
body['azure_user_delegation_sas'] = self.azure_user_delegation_sas.as_dict()
|
|
2573
2926
|
if self.expiration_time is not None: body['expiration_time'] = self.expiration_time
|
|
@@ -2580,6 +2933,7 @@ class GenerateTemporaryTableCredentialResponse:
|
|
|
2580
2933
|
def from_dict(cls, d: Dict[str, any]) -> GenerateTemporaryTableCredentialResponse:
|
|
2581
2934
|
"""Deserializes the GenerateTemporaryTableCredentialResponse from a dictionary."""
|
|
2582
2935
|
return cls(aws_temp_credentials=_from_dict(d, 'aws_temp_credentials', AwsCredentials),
|
|
2936
|
+
azure_aad=_from_dict(d, 'azure_aad', AzureActiveDirectoryToken),
|
|
2583
2937
|
azure_user_delegation_sas=_from_dict(d, 'azure_user_delegation_sas',
|
|
2584
2938
|
AzureUserDelegationSas),
|
|
2585
2939
|
expiration_time=d.get('expiration_time', None),
|
|
@@ -2592,6 +2946,7 @@ class GetBindingsSecurableType(Enum):
|
|
|
2592
2946
|
|
|
2593
2947
|
CATALOG = 'catalog'
|
|
2594
2948
|
EXTERNAL_LOCATION = 'external_location'
|
|
2949
|
+
SERVICE_CREDENTIAL = 'service_credential'
|
|
2595
2950
|
STORAGE_CREDENTIAL = 'storage_credential'
|
|
2596
2951
|
|
|
2597
2952
|
|
|
@@ -2738,7 +3093,6 @@ class GetQuotaResponse:
|
|
|
2738
3093
|
|
|
2739
3094
|
|
|
2740
3095
|
class IsolationMode(Enum):
|
|
2741
|
-
"""Whether the current securable is accessible from all workspaces or a specific set of workspaces."""
|
|
2742
3096
|
|
|
2743
3097
|
ISOLATION_MODE_ISOLATED = 'ISOLATION_MODE_ISOLATED'
|
|
2744
3098
|
ISOLATION_MODE_OPEN = 'ISOLATION_MODE_OPEN'
|
|
@@ -2826,6 +3180,28 @@ class ListConnectionsResponse:
|
|
|
2826
3180
|
next_page_token=d.get('next_page_token', None))
|
|
2827
3181
|
|
|
2828
3182
|
|
|
3183
|
+
@dataclass
|
|
3184
|
+
class ListCredentialsResponse:
|
|
3185
|
+
credentials: Optional[List[CredentialInfo]] = None
|
|
3186
|
+
|
|
3187
|
+
next_page_token: Optional[str] = None
|
|
3188
|
+
"""Opaque token to retrieve the next page of results. Absent if there are no more pages.
|
|
3189
|
+
__page_token__ should be set to this value for the next request (for the next page of results)."""
|
|
3190
|
+
|
|
3191
|
+
def as_dict(self) -> dict:
|
|
3192
|
+
"""Serializes the ListCredentialsResponse into a dictionary suitable for use as a JSON request body."""
|
|
3193
|
+
body = {}
|
|
3194
|
+
if self.credentials: body['credentials'] = [v.as_dict() for v in self.credentials]
|
|
3195
|
+
if self.next_page_token is not None: body['next_page_token'] = self.next_page_token
|
|
3196
|
+
return body
|
|
3197
|
+
|
|
3198
|
+
@classmethod
|
|
3199
|
+
def from_dict(cls, d: Dict[str, any]) -> ListCredentialsResponse:
|
|
3200
|
+
"""Deserializes the ListCredentialsResponse from a dictionary."""
|
|
3201
|
+
return cls(credentials=_repeated_dict(d, 'credentials', CredentialInfo),
|
|
3202
|
+
next_page_token=d.get('next_page_token', None))
|
|
3203
|
+
|
|
3204
|
+
|
|
2829
3205
|
@dataclass
|
|
2830
3206
|
class ListExternalLocationsResponse:
|
|
2831
3207
|
external_locations: Optional[List[ExternalLocationInfo]] = None
|
|
@@ -4619,6 +4995,7 @@ class SecurableType(Enum):
|
|
|
4619
4995
|
|
|
4620
4996
|
CATALOG = 'catalog'
|
|
4621
4997
|
CONNECTION = 'connection'
|
|
4998
|
+
CREDENTIAL = 'credential'
|
|
4622
4999
|
EXTERNAL_LOCATION = 'external_location'
|
|
4623
5000
|
FUNCTION = 'function'
|
|
4624
5001
|
METASTORE = 'metastore'
|
|
@@ -4738,11 +5115,13 @@ class StorageCredentialInfo:
|
|
|
4738
5115
|
databricks_gcp_service_account: Optional[DatabricksGcpServiceAccountResponse] = None
|
|
4739
5116
|
"""The Databricks managed GCP service account configuration."""
|
|
4740
5117
|
|
|
5118
|
+
full_name: Optional[str] = None
|
|
5119
|
+
"""The full name of the credential."""
|
|
5120
|
+
|
|
4741
5121
|
id: Optional[str] = None
|
|
4742
5122
|
"""The unique identifier of the credential."""
|
|
4743
5123
|
|
|
4744
5124
|
isolation_mode: Optional[IsolationMode] = None
|
|
4745
|
-
"""Whether the current securable is accessible from all workspaces or a specific set of workspaces."""
|
|
4746
5125
|
|
|
4747
5126
|
metastore_id: Optional[str] = None
|
|
4748
5127
|
"""Unique identifier of parent metastore."""
|
|
@@ -4778,6 +5157,7 @@ class StorageCredentialInfo:
|
|
|
4778
5157
|
if self.created_by is not None: body['created_by'] = self.created_by
|
|
4779
5158
|
if self.databricks_gcp_service_account:
|
|
4780
5159
|
body['databricks_gcp_service_account'] = self.databricks_gcp_service_account.as_dict()
|
|
5160
|
+
if self.full_name is not None: body['full_name'] = self.full_name
|
|
4781
5161
|
if self.id is not None: body['id'] = self.id
|
|
4782
5162
|
if self.isolation_mode is not None: body['isolation_mode'] = self.isolation_mode.value
|
|
4783
5163
|
if self.metastore_id is not None: body['metastore_id'] = self.metastore_id
|
|
@@ -4803,6 +5183,7 @@ class StorageCredentialInfo:
|
|
|
4803
5183
|
created_by=d.get('created_by', None),
|
|
4804
5184
|
databricks_gcp_service_account=_from_dict(d, 'databricks_gcp_service_account',
|
|
4805
5185
|
DatabricksGcpServiceAccountResponse),
|
|
5186
|
+
full_name=d.get('full_name', None),
|
|
4806
5187
|
id=d.get('id', None),
|
|
4807
5188
|
isolation_mode=_enum(d, 'isolation_mode', IsolationMode),
|
|
4808
5189
|
metastore_id=d.get('metastore_id', None),
|
|
@@ -5158,6 +5539,37 @@ class TableType(Enum):
|
|
|
5158
5539
|
VIEW = 'VIEW'
|
|
5159
5540
|
|
|
5160
5541
|
|
|
5542
|
+
@dataclass
|
|
5543
|
+
class TemporaryCredentials:
|
|
5544
|
+
aws_temp_credentials: Optional[AwsCredentials] = None
|
|
5545
|
+
"""AWS temporary credentials for API authentication. Read more at
|
|
5546
|
+
https://docs.aws.amazon.com/STS/latest/APIReference/API_Credentials.html."""
|
|
5547
|
+
|
|
5548
|
+
azure_aad: Optional[AzureActiveDirectoryToken] = None
|
|
5549
|
+
"""Azure Active Directory token, essentially the Oauth token for Azure Service Principal or Managed
|
|
5550
|
+
Identity. Read more at
|
|
5551
|
+
https://learn.microsoft.com/en-us/azure/databricks/dev-tools/api/latest/aad/service-prin-aad-token"""
|
|
5552
|
+
|
|
5553
|
+
expiration_time: Optional[int] = None
|
|
5554
|
+
"""Server time when the credential will expire, in epoch milliseconds. The API client is advised to
|
|
5555
|
+
cache the credential given this expiration time."""
|
|
5556
|
+
|
|
5557
|
+
def as_dict(self) -> dict:
|
|
5558
|
+
"""Serializes the TemporaryCredentials into a dictionary suitable for use as a JSON request body."""
|
|
5559
|
+
body = {}
|
|
5560
|
+
if self.aws_temp_credentials: body['aws_temp_credentials'] = self.aws_temp_credentials.as_dict()
|
|
5561
|
+
if self.azure_aad: body['azure_aad'] = self.azure_aad.as_dict()
|
|
5562
|
+
if self.expiration_time is not None: body['expiration_time'] = self.expiration_time
|
|
5563
|
+
return body
|
|
5564
|
+
|
|
5565
|
+
@classmethod
|
|
5566
|
+
def from_dict(cls, d: Dict[str, any]) -> TemporaryCredentials:
|
|
5567
|
+
"""Deserializes the TemporaryCredentials from a dictionary."""
|
|
5568
|
+
return cls(aws_temp_credentials=_from_dict(d, 'aws_temp_credentials', AwsCredentials),
|
|
5569
|
+
azure_aad=_from_dict(d, 'azure_aad', AzureActiveDirectoryToken),
|
|
5570
|
+
expiration_time=d.get('expiration_time', None))
|
|
5571
|
+
|
|
5572
|
+
|
|
5161
5573
|
@dataclass
|
|
5162
5574
|
class TriggeredUpdateStatus:
|
|
5163
5575
|
"""Detailed status of an online table. Shown if the online table is in the ONLINE_TRIGGERED_UPDATE
|
|
@@ -5224,6 +5636,7 @@ class UpdateBindingsSecurableType(Enum):
|
|
|
5224
5636
|
|
|
5225
5637
|
CATALOG = 'catalog'
|
|
5226
5638
|
EXTERNAL_LOCATION = 'external_location'
|
|
5639
|
+
SERVICE_CREDENTIAL = 'service_credential'
|
|
5227
5640
|
STORAGE_CREDENTIAL = 'storage_credential'
|
|
5228
5641
|
|
|
5229
5642
|
|
|
@@ -5308,6 +5721,76 @@ class UpdateConnection:
|
|
|
5308
5721
|
owner=d.get('owner', None))
|
|
5309
5722
|
|
|
5310
5723
|
|
|
5724
|
+
@dataclass
|
|
5725
|
+
class UpdateCredentialRequest:
|
|
5726
|
+
aws_iam_role: Optional[AwsIamRole] = None
|
|
5727
|
+
"""The AWS IAM role configuration"""
|
|
5728
|
+
|
|
5729
|
+
azure_managed_identity: Optional[AzureManagedIdentity] = None
|
|
5730
|
+
"""The Azure managed identity configuration."""
|
|
5731
|
+
|
|
5732
|
+
azure_service_principal: Optional[AzureServicePrincipal] = None
|
|
5733
|
+
"""The Azure service principal configuration."""
|
|
5734
|
+
|
|
5735
|
+
comment: Optional[str] = None
|
|
5736
|
+
"""Comment associated with the credential."""
|
|
5737
|
+
|
|
5738
|
+
force: Optional[bool] = None
|
|
5739
|
+
"""Force an update even if there are dependent services (when purpose is **SERVICE**) or dependent
|
|
5740
|
+
external locations and external tables (when purpose is **STORAGE**)."""
|
|
5741
|
+
|
|
5742
|
+
isolation_mode: Optional[IsolationMode] = None
|
|
5743
|
+
"""Whether the current securable is accessible from all workspaces or a specific set of workspaces."""
|
|
5744
|
+
|
|
5745
|
+
name_arg: Optional[str] = None
|
|
5746
|
+
"""Name of the credential."""
|
|
5747
|
+
|
|
5748
|
+
new_name: Optional[str] = None
|
|
5749
|
+
"""New name of credential."""
|
|
5750
|
+
|
|
5751
|
+
owner: Optional[str] = None
|
|
5752
|
+
"""Username of current owner of credential."""
|
|
5753
|
+
|
|
5754
|
+
read_only: Optional[bool] = None
|
|
5755
|
+
"""Whether the credential is usable only for read operations. Only applicable when purpose is
|
|
5756
|
+
**STORAGE**."""
|
|
5757
|
+
|
|
5758
|
+
skip_validation: Optional[bool] = None
|
|
5759
|
+
"""Supply true to this argument to skip validation of the updated credential."""
|
|
5760
|
+
|
|
5761
|
+
def as_dict(self) -> dict:
|
|
5762
|
+
"""Serializes the UpdateCredentialRequest into a dictionary suitable for use as a JSON request body."""
|
|
5763
|
+
body = {}
|
|
5764
|
+
if self.aws_iam_role: body['aws_iam_role'] = self.aws_iam_role.as_dict()
|
|
5765
|
+
if self.azure_managed_identity: body['azure_managed_identity'] = self.azure_managed_identity.as_dict()
|
|
5766
|
+
if self.azure_service_principal:
|
|
5767
|
+
body['azure_service_principal'] = self.azure_service_principal.as_dict()
|
|
5768
|
+
if self.comment is not None: body['comment'] = self.comment
|
|
5769
|
+
if self.force is not None: body['force'] = self.force
|
|
5770
|
+
if self.isolation_mode is not None: body['isolation_mode'] = self.isolation_mode.value
|
|
5771
|
+
if self.name_arg is not None: body['name_arg'] = self.name_arg
|
|
5772
|
+
if self.new_name is not None: body['new_name'] = self.new_name
|
|
5773
|
+
if self.owner is not None: body['owner'] = self.owner
|
|
5774
|
+
if self.read_only is not None: body['read_only'] = self.read_only
|
|
5775
|
+
if self.skip_validation is not None: body['skip_validation'] = self.skip_validation
|
|
5776
|
+
return body
|
|
5777
|
+
|
|
5778
|
+
@classmethod
|
|
5779
|
+
def from_dict(cls, d: Dict[str, any]) -> UpdateCredentialRequest:
|
|
5780
|
+
"""Deserializes the UpdateCredentialRequest from a dictionary."""
|
|
5781
|
+
return cls(aws_iam_role=_from_dict(d, 'aws_iam_role', AwsIamRole),
|
|
5782
|
+
azure_managed_identity=_from_dict(d, 'azure_managed_identity', AzureManagedIdentity),
|
|
5783
|
+
azure_service_principal=_from_dict(d, 'azure_service_principal', AzureServicePrincipal),
|
|
5784
|
+
comment=d.get('comment', None),
|
|
5785
|
+
force=d.get('force', None),
|
|
5786
|
+
isolation_mode=_enum(d, 'isolation_mode', IsolationMode),
|
|
5787
|
+
name_arg=d.get('name_arg', None),
|
|
5788
|
+
new_name=d.get('new_name', None),
|
|
5789
|
+
owner=d.get('owner', None),
|
|
5790
|
+
read_only=d.get('read_only', None),
|
|
5791
|
+
skip_validation=d.get('skip_validation', None))
|
|
5792
|
+
|
|
5793
|
+
|
|
5311
5794
|
@dataclass
|
|
5312
5795
|
class UpdateExternalLocation:
|
|
5313
5796
|
access_point: Optional[str] = None
|
|
@@ -5331,7 +5814,6 @@ class UpdateExternalLocation:
|
|
|
5331
5814
|
"""Force update even if changing url invalidates dependent external tables or mounts."""
|
|
5332
5815
|
|
|
5333
5816
|
isolation_mode: Optional[IsolationMode] = None
|
|
5334
|
-
"""Whether the current securable is accessible from all workspaces or a specific set of workspaces."""
|
|
5335
5817
|
|
|
5336
5818
|
name: Optional[str] = None
|
|
5337
5819
|
"""Name of the external location."""
|
|
@@ -5751,7 +6233,6 @@ class UpdateStorageCredential:
|
|
|
5751
6233
|
"""Force update even if there are dependent external locations or external tables."""
|
|
5752
6234
|
|
|
5753
6235
|
isolation_mode: Optional[IsolationMode] = None
|
|
5754
|
-
"""Whether the current securable is accessible from all workspaces or a specific set of workspaces."""
|
|
5755
6236
|
|
|
5756
6237
|
name: Optional[str] = None
|
|
5757
6238
|
"""Name of the storage credential."""
|
|
@@ -5899,6 +6380,87 @@ class UpdateWorkspaceBindingsParameters:
|
|
|
5899
6380
|
securable_type=_enum(d, 'securable_type', UpdateBindingsSecurableType))
|
|
5900
6381
|
|
|
5901
6382
|
|
|
6383
|
+
@dataclass
|
|
6384
|
+
class ValidateCredentialRequest:
|
|
6385
|
+
aws_iam_role: Optional[AwsIamRole] = None
|
|
6386
|
+
"""The AWS IAM role configuration"""
|
|
6387
|
+
|
|
6388
|
+
azure_managed_identity: Optional[AzureManagedIdentity] = None
|
|
6389
|
+
"""The Azure managed identity configuration."""
|
|
6390
|
+
|
|
6391
|
+
credential_name: Optional[str] = None
|
|
6392
|
+
"""Required. The name of an existing credential or long-lived cloud credential to validate."""
|
|
6393
|
+
|
|
6394
|
+
external_location_name: Optional[str] = None
|
|
6395
|
+
"""The name of an existing external location to validate. Only applicable for storage credentials
|
|
6396
|
+
(purpose is **STORAGE**.)"""
|
|
6397
|
+
|
|
6398
|
+
purpose: Optional[CredentialPurpose] = None
|
|
6399
|
+
"""The purpose of the credential. This should only be used when the credential is specified."""
|
|
6400
|
+
|
|
6401
|
+
read_only: Optional[bool] = None
|
|
6402
|
+
"""Whether the credential is only usable for read operations. Only applicable for storage
|
|
6403
|
+
credentials (purpose is **STORAGE**.)"""
|
|
6404
|
+
|
|
6405
|
+
url: Optional[str] = None
|
|
6406
|
+
"""The external location url to validate. Only applicable when purpose is **STORAGE**."""
|
|
6407
|
+
|
|
6408
|
+
def as_dict(self) -> dict:
|
|
6409
|
+
"""Serializes the ValidateCredentialRequest into a dictionary suitable for use as a JSON request body."""
|
|
6410
|
+
body = {}
|
|
6411
|
+
if self.aws_iam_role: body['aws_iam_role'] = self.aws_iam_role.as_dict()
|
|
6412
|
+
if self.azure_managed_identity: body['azure_managed_identity'] = self.azure_managed_identity.as_dict()
|
|
6413
|
+
if self.credential_name is not None: body['credential_name'] = self.credential_name
|
|
6414
|
+
if self.external_location_name is not None:
|
|
6415
|
+
body['external_location_name'] = self.external_location_name
|
|
6416
|
+
if self.purpose is not None: body['purpose'] = self.purpose.value
|
|
6417
|
+
if self.read_only is not None: body['read_only'] = self.read_only
|
|
6418
|
+
if self.url is not None: body['url'] = self.url
|
|
6419
|
+
return body
|
|
6420
|
+
|
|
6421
|
+
@classmethod
|
|
6422
|
+
def from_dict(cls, d: Dict[str, any]) -> ValidateCredentialRequest:
|
|
6423
|
+
"""Deserializes the ValidateCredentialRequest from a dictionary."""
|
|
6424
|
+
return cls(aws_iam_role=_from_dict(d, 'aws_iam_role', AwsIamRole),
|
|
6425
|
+
azure_managed_identity=_from_dict(d, 'azure_managed_identity', AzureManagedIdentity),
|
|
6426
|
+
credential_name=d.get('credential_name', None),
|
|
6427
|
+
external_location_name=d.get('external_location_name', None),
|
|
6428
|
+
purpose=_enum(d, 'purpose', CredentialPurpose),
|
|
6429
|
+
read_only=d.get('read_only', None),
|
|
6430
|
+
url=d.get('url', None))
|
|
6431
|
+
|
|
6432
|
+
|
|
6433
|
+
@dataclass
|
|
6434
|
+
class ValidateCredentialResponse:
|
|
6435
|
+
is_dir: Optional[bool] = None
|
|
6436
|
+
"""Whether the tested location is a directory in cloud storage. Only applicable for when purpose is
|
|
6437
|
+
**STORAGE**."""
|
|
6438
|
+
|
|
6439
|
+
results: Optional[List[CredentialValidationResult]] = None
|
|
6440
|
+
"""The results of the validation check."""
|
|
6441
|
+
|
|
6442
|
+
def as_dict(self) -> dict:
|
|
6443
|
+
"""Serializes the ValidateCredentialResponse into a dictionary suitable for use as a JSON request body."""
|
|
6444
|
+
body = {}
|
|
6445
|
+
if self.is_dir is not None: body['isDir'] = self.is_dir
|
|
6446
|
+
if self.results: body['results'] = [v.as_dict() for v in self.results]
|
|
6447
|
+
return body
|
|
6448
|
+
|
|
6449
|
+
@classmethod
|
|
6450
|
+
def from_dict(cls, d: Dict[str, any]) -> ValidateCredentialResponse:
|
|
6451
|
+
"""Deserializes the ValidateCredentialResponse from a dictionary."""
|
|
6452
|
+
return cls(is_dir=d.get('isDir', None),
|
|
6453
|
+
results=_repeated_dict(d, 'results', CredentialValidationResult))
|
|
6454
|
+
|
|
6455
|
+
|
|
6456
|
+
class ValidateCredentialResult(Enum):
|
|
6457
|
+
"""A enum represents the result of the file operation"""
|
|
6458
|
+
|
|
6459
|
+
FAIL = 'FAIL'
|
|
6460
|
+
PASS = 'PASS'
|
|
6461
|
+
SKIP = 'SKIP'
|
|
6462
|
+
|
|
6463
|
+
|
|
5902
6464
|
@dataclass
|
|
5903
6465
|
class ValidateStorageCredential:
|
|
5904
6466
|
aws_iam_role: Optional[AwsIamRoleRequest] = None
|
|
@@ -6935,6 +7497,312 @@ class ConnectionsAPI:
|
|
|
6935
7497
|
return ConnectionInfo.from_dict(res)
|
|
6936
7498
|
|
|
6937
7499
|
|
|
7500
|
+
class CredentialsAPI:
|
|
7501
|
+
"""A credential represents an authentication and authorization mechanism for accessing services on your cloud
|
|
7502
|
+
tenant. Each credential is subject to Unity Catalog access-control policies that control which users and
|
|
7503
|
+
groups can access the credential.
|
|
7504
|
+
|
|
7505
|
+
To create credentials, you must be a Databricks account admin or have the `CREATE SERVICE CREDENTIAL
|
|
7506
|
+
privilege. The user who creates the credential can delegate ownership to another user or group to manage
|
|
7507
|
+
permissions on it"""
|
|
7508
|
+
|
|
7509
|
+
def __init__(self, api_client):
|
|
7510
|
+
self._api = api_client
|
|
7511
|
+
|
|
7512
|
+
def create_credential(self,
|
|
7513
|
+
name: str,
|
|
7514
|
+
*,
|
|
7515
|
+
aws_iam_role: Optional[AwsIamRole] = None,
|
|
7516
|
+
azure_managed_identity: Optional[AzureManagedIdentity] = None,
|
|
7517
|
+
azure_service_principal: Optional[AzureServicePrincipal] = None,
|
|
7518
|
+
comment: Optional[str] = None,
|
|
7519
|
+
gcp_service_account_key: Optional[GcpServiceAccountKey] = None,
|
|
7520
|
+
purpose: Optional[CredentialPurpose] = None,
|
|
7521
|
+
read_only: Optional[bool] = None,
|
|
7522
|
+
skip_validation: Optional[bool] = None) -> CredentialInfo:
|
|
7523
|
+
"""Create a credential.
|
|
7524
|
+
|
|
7525
|
+
Creates a new credential. The type of credential to be created is determined by the **purpose** field,
|
|
7526
|
+
which should be either **SERVICE** or **STORAGE**.
|
|
7527
|
+
|
|
7528
|
+
The caller must be a metastore admin or have the metastore privilege **CREATE_STORAGE_CREDENTIAL** for
|
|
7529
|
+
storage credentials, or **CREATE_SERVICE_CREDENTIAL** for service credentials.
|
|
7530
|
+
|
|
7531
|
+
:param name: str
|
|
7532
|
+
The credential name. The name must be unique among storage and service credentials within the
|
|
7533
|
+
metastore.
|
|
7534
|
+
:param aws_iam_role: :class:`AwsIamRole` (optional)
|
|
7535
|
+
The AWS IAM role configuration
|
|
7536
|
+
:param azure_managed_identity: :class:`AzureManagedIdentity` (optional)
|
|
7537
|
+
The Azure managed identity configuration.
|
|
7538
|
+
:param azure_service_principal: :class:`AzureServicePrincipal` (optional)
|
|
7539
|
+
The Azure service principal configuration.
|
|
7540
|
+
:param comment: str (optional)
|
|
7541
|
+
Comment associated with the credential.
|
|
7542
|
+
:param gcp_service_account_key: :class:`GcpServiceAccountKey` (optional)
|
|
7543
|
+
:param purpose: :class:`CredentialPurpose` (optional)
|
|
7544
|
+
Indicates the purpose of the credential.
|
|
7545
|
+
:param read_only: bool (optional)
|
|
7546
|
+
Whether the credential is usable only for read operations. Only applicable when purpose is
|
|
7547
|
+
**STORAGE**.
|
|
7548
|
+
:param skip_validation: bool (optional)
|
|
7549
|
+
Optional. Supplying true to this argument skips validation of the created set of credentials.
|
|
7550
|
+
|
|
7551
|
+
:returns: :class:`CredentialInfo`
|
|
7552
|
+
"""
|
|
7553
|
+
body = {}
|
|
7554
|
+
if aws_iam_role is not None: body['aws_iam_role'] = aws_iam_role.as_dict()
|
|
7555
|
+
if azure_managed_identity is not None:
|
|
7556
|
+
body['azure_managed_identity'] = azure_managed_identity.as_dict()
|
|
7557
|
+
if azure_service_principal is not None:
|
|
7558
|
+
body['azure_service_principal'] = azure_service_principal.as_dict()
|
|
7559
|
+
if comment is not None: body['comment'] = comment
|
|
7560
|
+
if gcp_service_account_key is not None:
|
|
7561
|
+
body['gcp_service_account_key'] = gcp_service_account_key.as_dict()
|
|
7562
|
+
if name is not None: body['name'] = name
|
|
7563
|
+
if purpose is not None: body['purpose'] = purpose.value
|
|
7564
|
+
if read_only is not None: body['read_only'] = read_only
|
|
7565
|
+
if skip_validation is not None: body['skip_validation'] = skip_validation
|
|
7566
|
+
headers = {'Accept': 'application/json', 'Content-Type': 'application/json', }
|
|
7567
|
+
|
|
7568
|
+
res = self._api.do('POST', '/api/2.1/unity-catalog/credentials', body=body, headers=headers)
|
|
7569
|
+
return CredentialInfo.from_dict(res)
|
|
7570
|
+
|
|
7571
|
+
def delete_credential(self, name_arg: str, *, force: Optional[bool] = None):
|
|
7572
|
+
"""Delete a credential.
|
|
7573
|
+
|
|
7574
|
+
Deletes a service or storage credential from the metastore. The caller must be an owner of the
|
|
7575
|
+
credential.
|
|
7576
|
+
|
|
7577
|
+
:param name_arg: str
|
|
7578
|
+
Name of the credential.
|
|
7579
|
+
:param force: bool (optional)
|
|
7580
|
+
Force an update even if there are dependent services (when purpose is **SERVICE**) or dependent
|
|
7581
|
+
external locations and external tables (when purpose is **STORAGE**).
|
|
7582
|
+
|
|
7583
|
+
|
|
7584
|
+
"""
|
|
7585
|
+
|
|
7586
|
+
query = {}
|
|
7587
|
+
if force is not None: query['force'] = force
|
|
7588
|
+
headers = {'Accept': 'application/json', }
|
|
7589
|
+
|
|
7590
|
+
self._api.do('DELETE', f'/api/2.1/unity-catalog/credentials/{name_arg}', query=query, headers=headers)
|
|
7591
|
+
|
|
7592
|
+
def generate_temporary_service_credential(
|
|
7593
|
+
self,
|
|
7594
|
+
credential_name: str,
|
|
7595
|
+
*,
|
|
7596
|
+
azure_options: Optional[GenerateTemporaryServiceCredentialAzureOptions] = None
|
|
7597
|
+
) -> TemporaryCredentials:
|
|
7598
|
+
"""Generate a temporary service credential.
|
|
7599
|
+
|
|
7600
|
+
Returns a set of temporary credentials generated using the specified service credential. The caller
|
|
7601
|
+
must be a metastore admin or have the metastore privilege **ACCESS** on the service credential.
|
|
7602
|
+
|
|
7603
|
+
:param credential_name: str
|
|
7604
|
+
The name of the service credential used to generate a temporary credential
|
|
7605
|
+
:param azure_options: :class:`GenerateTemporaryServiceCredentialAzureOptions` (optional)
|
|
7606
|
+
Options to customize the requested temporary credential
|
|
7607
|
+
|
|
7608
|
+
:returns: :class:`TemporaryCredentials`
|
|
7609
|
+
"""
|
|
7610
|
+
body = {}
|
|
7611
|
+
if azure_options is not None: body['azure_options'] = azure_options.as_dict()
|
|
7612
|
+
if credential_name is not None: body['credential_name'] = credential_name
|
|
7613
|
+
headers = {'Accept': 'application/json', 'Content-Type': 'application/json', }
|
|
7614
|
+
|
|
7615
|
+
res = self._api.do('POST',
|
|
7616
|
+
'/api/2.1/unity-catalog/temporary-service-credentials',
|
|
7617
|
+
body=body,
|
|
7618
|
+
headers=headers)
|
|
7619
|
+
return TemporaryCredentials.from_dict(res)
|
|
7620
|
+
|
|
7621
|
+
def get_credential(self, name_arg: str) -> CredentialInfo:
|
|
7622
|
+
"""Get a credential.
|
|
7623
|
+
|
|
7624
|
+
Gets a service or storage credential from the metastore. The caller must be a metastore admin, the
|
|
7625
|
+
owner of the credential, or have any permission on the credential.
|
|
7626
|
+
|
|
7627
|
+
:param name_arg: str
|
|
7628
|
+
Name of the credential.
|
|
7629
|
+
|
|
7630
|
+
:returns: :class:`CredentialInfo`
|
|
7631
|
+
"""
|
|
7632
|
+
|
|
7633
|
+
headers = {'Accept': 'application/json', }
|
|
7634
|
+
|
|
7635
|
+
res = self._api.do('GET', f'/api/2.1/unity-catalog/credentials/{name_arg}', headers=headers)
|
|
7636
|
+
return CredentialInfo.from_dict(res)
|
|
7637
|
+
|
|
7638
|
+
def list_credentials(self,
|
|
7639
|
+
*,
|
|
7640
|
+
max_results: Optional[int] = None,
|
|
7641
|
+
page_token: Optional[str] = None,
|
|
7642
|
+
purpose: Optional[CredentialPurpose] = None) -> Iterator[CredentialInfo]:
|
|
7643
|
+
"""List credentials.
|
|
7644
|
+
|
|
7645
|
+
Gets an array of credentials (as __CredentialInfo__ objects).
|
|
7646
|
+
|
|
7647
|
+
The array is limited to only the credentials that the caller has permission to access. If the caller
|
|
7648
|
+
is a metastore admin, retrieval of credentials is unrestricted. There is no guarantee of a specific
|
|
7649
|
+
ordering of the elements in the array.
|
|
7650
|
+
|
|
7651
|
+
:param max_results: int (optional)
|
|
7652
|
+
Maximum number of credentials to return. - If not set, the default max page size is used. - When set
|
|
7653
|
+
to a value greater than 0, the page length is the minimum of this value and a server-configured
|
|
7654
|
+
value. - When set to 0, the page length is set to a server-configured value (recommended). - When
|
|
7655
|
+
set to a value less than 0, an invalid parameter error is returned.
|
|
7656
|
+
:param page_token: str (optional)
|
|
7657
|
+
Opaque token to retrieve the next page of results.
|
|
7658
|
+
:param purpose: :class:`CredentialPurpose` (optional)
|
|
7659
|
+
Return only credentials for the specified purpose.
|
|
7660
|
+
|
|
7661
|
+
:returns: Iterator over :class:`CredentialInfo`
|
|
7662
|
+
"""
|
|
7663
|
+
|
|
7664
|
+
query = {}
|
|
7665
|
+
if max_results is not None: query['max_results'] = max_results
|
|
7666
|
+
if page_token is not None: query['page_token'] = page_token
|
|
7667
|
+
if purpose is not None: query['purpose'] = purpose.value
|
|
7668
|
+
headers = {'Accept': 'application/json', }
|
|
7669
|
+
|
|
7670
|
+
while True:
|
|
7671
|
+
json = self._api.do('GET', '/api/2.1/unity-catalog/credentials', query=query, headers=headers)
|
|
7672
|
+
if 'credentials' in json:
|
|
7673
|
+
for v in json['credentials']:
|
|
7674
|
+
yield CredentialInfo.from_dict(v)
|
|
7675
|
+
if 'next_page_token' not in json or not json['next_page_token']:
|
|
7676
|
+
return
|
|
7677
|
+
query['page_token'] = json['next_page_token']
|
|
7678
|
+
|
|
7679
|
+
def update_credential(self,
|
|
7680
|
+
name_arg: str,
|
|
7681
|
+
*,
|
|
7682
|
+
aws_iam_role: Optional[AwsIamRole] = None,
|
|
7683
|
+
azure_managed_identity: Optional[AzureManagedIdentity] = None,
|
|
7684
|
+
azure_service_principal: Optional[AzureServicePrincipal] = None,
|
|
7685
|
+
comment: Optional[str] = None,
|
|
7686
|
+
force: Optional[bool] = None,
|
|
7687
|
+
isolation_mode: Optional[IsolationMode] = None,
|
|
7688
|
+
new_name: Optional[str] = None,
|
|
7689
|
+
owner: Optional[str] = None,
|
|
7690
|
+
read_only: Optional[bool] = None,
|
|
7691
|
+
skip_validation: Optional[bool] = None) -> CredentialInfo:
|
|
7692
|
+
"""Update a credential.
|
|
7693
|
+
|
|
7694
|
+
Updates a service or storage credential on the metastore.
|
|
7695
|
+
|
|
7696
|
+
The caller must be the owner of the credential or a metastore admin or have the `MANAGE` permission.
|
|
7697
|
+
If the caller is a metastore admin, only the __owner__ field can be changed.
|
|
7698
|
+
|
|
7699
|
+
:param name_arg: str
|
|
7700
|
+
Name of the credential.
|
|
7701
|
+
:param aws_iam_role: :class:`AwsIamRole` (optional)
|
|
7702
|
+
The AWS IAM role configuration
|
|
7703
|
+
:param azure_managed_identity: :class:`AzureManagedIdentity` (optional)
|
|
7704
|
+
The Azure managed identity configuration.
|
|
7705
|
+
:param azure_service_principal: :class:`AzureServicePrincipal` (optional)
|
|
7706
|
+
The Azure service principal configuration.
|
|
7707
|
+
:param comment: str (optional)
|
|
7708
|
+
Comment associated with the credential.
|
|
7709
|
+
:param force: bool (optional)
|
|
7710
|
+
Force an update even if there are dependent services (when purpose is **SERVICE**) or dependent
|
|
7711
|
+
external locations and external tables (when purpose is **STORAGE**).
|
|
7712
|
+
:param isolation_mode: :class:`IsolationMode` (optional)
|
|
7713
|
+
Whether the current securable is accessible from all workspaces or a specific set of workspaces.
|
|
7714
|
+
:param new_name: str (optional)
|
|
7715
|
+
New name of credential.
|
|
7716
|
+
:param owner: str (optional)
|
|
7717
|
+
Username of current owner of credential.
|
|
7718
|
+
:param read_only: bool (optional)
|
|
7719
|
+
Whether the credential is usable only for read operations. Only applicable when purpose is
|
|
7720
|
+
**STORAGE**.
|
|
7721
|
+
:param skip_validation: bool (optional)
|
|
7722
|
+
Supply true to this argument to skip validation of the updated credential.
|
|
7723
|
+
|
|
7724
|
+
:returns: :class:`CredentialInfo`
|
|
7725
|
+
"""
|
|
7726
|
+
body = {}
|
|
7727
|
+
if aws_iam_role is not None: body['aws_iam_role'] = aws_iam_role.as_dict()
|
|
7728
|
+
if azure_managed_identity is not None:
|
|
7729
|
+
body['azure_managed_identity'] = azure_managed_identity.as_dict()
|
|
7730
|
+
if azure_service_principal is not None:
|
|
7731
|
+
body['azure_service_principal'] = azure_service_principal.as_dict()
|
|
7732
|
+
if comment is not None: body['comment'] = comment
|
|
7733
|
+
if force is not None: body['force'] = force
|
|
7734
|
+
if isolation_mode is not None: body['isolation_mode'] = isolation_mode.value
|
|
7735
|
+
if new_name is not None: body['new_name'] = new_name
|
|
7736
|
+
if owner is not None: body['owner'] = owner
|
|
7737
|
+
if read_only is not None: body['read_only'] = read_only
|
|
7738
|
+
if skip_validation is not None: body['skip_validation'] = skip_validation
|
|
7739
|
+
headers = {'Accept': 'application/json', 'Content-Type': 'application/json', }
|
|
7740
|
+
|
|
7741
|
+
res = self._api.do('PATCH',
|
|
7742
|
+
f'/api/2.1/unity-catalog/credentials/{name_arg}',
|
|
7743
|
+
body=body,
|
|
7744
|
+
headers=headers)
|
|
7745
|
+
return CredentialInfo.from_dict(res)
|
|
7746
|
+
|
|
7747
|
+
def validate_credential(self,
|
|
7748
|
+
*,
|
|
7749
|
+
aws_iam_role: Optional[AwsIamRole] = None,
|
|
7750
|
+
azure_managed_identity: Optional[AzureManagedIdentity] = None,
|
|
7751
|
+
credential_name: Optional[str] = None,
|
|
7752
|
+
external_location_name: Optional[str] = None,
|
|
7753
|
+
purpose: Optional[CredentialPurpose] = None,
|
|
7754
|
+
read_only: Optional[bool] = None,
|
|
7755
|
+
url: Optional[str] = None) -> ValidateCredentialResponse:
|
|
7756
|
+
"""Validate a credential.
|
|
7757
|
+
|
|
7758
|
+
Validates a credential.
|
|
7759
|
+
|
|
7760
|
+
For service credentials (purpose is **SERVICE**), either the __credential_name__ or the cloud-specific
|
|
7761
|
+
credential must be provided.
|
|
7762
|
+
|
|
7763
|
+
For storage credentials (purpose is **STORAGE**), at least one of __external_location_name__ and
|
|
7764
|
+
__url__ need to be provided. If only one of them is provided, it will be used for validation. And if
|
|
7765
|
+
both are provided, the __url__ will be used for validation, and __external_location_name__ will be
|
|
7766
|
+
ignored when checking overlapping urls. Either the __credential_name__ or the cloud-specific
|
|
7767
|
+
credential must be provided.
|
|
7768
|
+
|
|
7769
|
+
The caller must be a metastore admin or the credential owner or have the required permission on the
|
|
7770
|
+
metastore and the credential (e.g., **CREATE_EXTERNAL_LOCATION** when purpose is **STORAGE**).
|
|
7771
|
+
|
|
7772
|
+
:param aws_iam_role: :class:`AwsIamRole` (optional)
|
|
7773
|
+
The AWS IAM role configuration
|
|
7774
|
+
:param azure_managed_identity: :class:`AzureManagedIdentity` (optional)
|
|
7775
|
+
The Azure managed identity configuration.
|
|
7776
|
+
:param credential_name: str (optional)
|
|
7777
|
+
Required. The name of an existing credential or long-lived cloud credential to validate.
|
|
7778
|
+
:param external_location_name: str (optional)
|
|
7779
|
+
The name of an existing external location to validate. Only applicable for storage credentials
|
|
7780
|
+
(purpose is **STORAGE**.)
|
|
7781
|
+
:param purpose: :class:`CredentialPurpose` (optional)
|
|
7782
|
+
The purpose of the credential. This should only be used when the credential is specified.
|
|
7783
|
+
:param read_only: bool (optional)
|
|
7784
|
+
Whether the credential is only usable for read operations. Only applicable for storage credentials
|
|
7785
|
+
(purpose is **STORAGE**.)
|
|
7786
|
+
:param url: str (optional)
|
|
7787
|
+
The external location url to validate. Only applicable when purpose is **STORAGE**.
|
|
7788
|
+
|
|
7789
|
+
:returns: :class:`ValidateCredentialResponse`
|
|
7790
|
+
"""
|
|
7791
|
+
body = {}
|
|
7792
|
+
if aws_iam_role is not None: body['aws_iam_role'] = aws_iam_role.as_dict()
|
|
7793
|
+
if azure_managed_identity is not None:
|
|
7794
|
+
body['azure_managed_identity'] = azure_managed_identity.as_dict()
|
|
7795
|
+
if credential_name is not None: body['credential_name'] = credential_name
|
|
7796
|
+
if external_location_name is not None: body['external_location_name'] = external_location_name
|
|
7797
|
+
if purpose is not None: body['purpose'] = purpose.value
|
|
7798
|
+
if read_only is not None: body['read_only'] = read_only
|
|
7799
|
+
if url is not None: body['url'] = url
|
|
7800
|
+
headers = {'Accept': 'application/json', 'Content-Type': 'application/json', }
|
|
7801
|
+
|
|
7802
|
+
res = self._api.do('POST', '/api/2.1/unity-catalog/validate-credentials', body=body, headers=headers)
|
|
7803
|
+
return ValidateCredentialResponse.from_dict(res)
|
|
7804
|
+
|
|
7805
|
+
|
|
6938
7806
|
class ExternalLocationsAPI:
|
|
6939
7807
|
"""An external location is an object that combines a cloud storage path with a storage credential that
|
|
6940
7808
|
authorizes access to the cloud storage path. Each external location is subject to Unity Catalog
|
|
@@ -7134,7 +8002,6 @@ class ExternalLocationsAPI:
|
|
|
7134
8002
|
:param force: bool (optional)
|
|
7135
8003
|
Force update even if changing url invalidates dependent external tables or mounts.
|
|
7136
8004
|
:param isolation_mode: :class:`IsolationMode` (optional)
|
|
7137
|
-
Whether the current securable is accessible from all workspaces or a specific set of workspaces.
|
|
7138
8005
|
:param new_name: str (optional)
|
|
7139
8006
|
New name for the external location.
|
|
7140
8007
|
:param owner: str (optional)
|
|
@@ -7890,25 +8757,61 @@ class OnlineTablesAPI:
|
|
|
7890
8757
|
def __init__(self, api_client):
|
|
7891
8758
|
self._api = api_client
|
|
7892
8759
|
|
|
7893
|
-
def
|
|
8760
|
+
def wait_get_online_table_active(self,
|
|
8761
|
+
name: str,
|
|
8762
|
+
timeout=timedelta(minutes=20),
|
|
8763
|
+
callback: Optional[Callable[[OnlineTable], None]] = None) -> OnlineTable:
|
|
8764
|
+
deadline = time.time() + timeout.total_seconds()
|
|
8765
|
+
target_states = (ProvisioningInfoState.ACTIVE, )
|
|
8766
|
+
failure_states = (ProvisioningInfoState.FAILED, )
|
|
8767
|
+
status_message = 'polling...'
|
|
8768
|
+
attempt = 1
|
|
8769
|
+
while time.time() < deadline:
|
|
8770
|
+
poll = self.get(name=name)
|
|
8771
|
+
status = poll.unity_catalog_provisioning_state
|
|
8772
|
+
status_message = f'current status: {status}'
|
|
8773
|
+
if status in target_states:
|
|
8774
|
+
return poll
|
|
8775
|
+
if callback:
|
|
8776
|
+
callback(poll)
|
|
8777
|
+
if status in failure_states:
|
|
8778
|
+
msg = f'failed to reach ACTIVE, got {status}: {status_message}'
|
|
8779
|
+
raise OperationFailed(msg)
|
|
8780
|
+
prefix = f"name={name}"
|
|
8781
|
+
sleep = attempt
|
|
8782
|
+
if sleep > 10:
|
|
8783
|
+
# sleep 10s max per attempt
|
|
8784
|
+
sleep = 10
|
|
8785
|
+
_LOG.debug(f'{prefix}: ({status}) {status_message} (sleeping ~{sleep}s)')
|
|
8786
|
+
time.sleep(sleep + random.random())
|
|
8787
|
+
attempt += 1
|
|
8788
|
+
raise TimeoutError(f'timed out after {timeout}: {status_message}')
|
|
8789
|
+
|
|
8790
|
+
def create(self, *, table: Optional[OnlineTable] = None) -> Wait[OnlineTable]:
|
|
7894
8791
|
"""Create an Online Table.
|
|
7895
8792
|
|
|
7896
8793
|
Create a new Online Table.
|
|
7897
8794
|
|
|
7898
|
-
:param
|
|
7899
|
-
|
|
7900
|
-
:param spec: :class:`OnlineTableSpec` (optional)
|
|
7901
|
-
Specification of the online table.
|
|
8795
|
+
:param table: :class:`OnlineTable` (optional)
|
|
8796
|
+
Online Table information.
|
|
7902
8797
|
|
|
7903
|
-
:returns:
|
|
8798
|
+
:returns:
|
|
8799
|
+
Long-running operation waiter for :class:`OnlineTable`.
|
|
8800
|
+
See :method:wait_get_online_table_active for more details.
|
|
7904
8801
|
"""
|
|
7905
|
-
body =
|
|
7906
|
-
if name is not None: body['name'] = name
|
|
7907
|
-
if spec is not None: body['spec'] = spec.as_dict()
|
|
8802
|
+
body = table.as_dict()
|
|
7908
8803
|
headers = {'Accept': 'application/json', 'Content-Type': 'application/json', }
|
|
7909
8804
|
|
|
7910
|
-
|
|
7911
|
-
return
|
|
8805
|
+
op_response = self._api.do('POST', '/api/2.0/online-tables', body=body, headers=headers)
|
|
8806
|
+
return Wait(self.wait_get_online_table_active,
|
|
8807
|
+
response=OnlineTable.from_dict(op_response),
|
|
8808
|
+
name=op_response['name'])
|
|
8809
|
+
|
|
8810
|
+
def create_and_wait(self,
|
|
8811
|
+
*,
|
|
8812
|
+
table: Optional[OnlineTable] = None,
|
|
8813
|
+
timeout=timedelta(minutes=20)) -> OnlineTable:
|
|
8814
|
+
return self.create(table=table).result(timeout=timeout)
|
|
7912
8815
|
|
|
7913
8816
|
def delete(self, name: str):
|
|
7914
8817
|
"""Delete an Online Table.
|
|
@@ -9019,7 +9922,6 @@ class StorageCredentialsAPI:
|
|
|
9019
9922
|
:param force: bool (optional)
|
|
9020
9923
|
Force update even if there are dependent external locations or external tables.
|
|
9021
9924
|
:param isolation_mode: :class:`IsolationMode` (optional)
|
|
9022
|
-
Whether the current securable is accessible from all workspaces or a specific set of workspaces.
|
|
9023
9925
|
:param new_name: str (optional)
|
|
9024
9926
|
New name for the storage credential.
|
|
9025
9927
|
:param owner: str (optional)
|
|
@@ -9385,6 +10287,7 @@ class TablesAPI:
|
|
|
9385
10287
|
max_results: Optional[int] = None,
|
|
9386
10288
|
omit_columns: Optional[bool] = None,
|
|
9387
10289
|
omit_properties: Optional[bool] = None,
|
|
10290
|
+
omit_username: Optional[bool] = None,
|
|
9388
10291
|
page_token: Optional[str] = None) -> Iterator[TableInfo]:
|
|
9389
10292
|
"""List tables.
|
|
9390
10293
|
|
|
@@ -9414,6 +10317,9 @@ class TablesAPI:
|
|
|
9414
10317
|
Whether to omit the columns of the table from the response or not.
|
|
9415
10318
|
:param omit_properties: bool (optional)
|
|
9416
10319
|
Whether to omit the properties of the table from the response or not.
|
|
10320
|
+
:param omit_username: bool (optional)
|
|
10321
|
+
Whether to omit the username of the table (e.g. owner, updated_by, created_by) from the response or
|
|
10322
|
+
not.
|
|
9417
10323
|
:param page_token: str (optional)
|
|
9418
10324
|
Opaque token to send for the next page of results (pagination).
|
|
9419
10325
|
|
|
@@ -9429,6 +10335,7 @@ class TablesAPI:
|
|
|
9429
10335
|
if max_results is not None: query['max_results'] = max_results
|
|
9430
10336
|
if omit_columns is not None: query['omit_columns'] = omit_columns
|
|
9431
10337
|
if omit_properties is not None: query['omit_properties'] = omit_properties
|
|
10338
|
+
if omit_username is not None: query['omit_username'] = omit_username
|
|
9432
10339
|
if page_token is not None: query['page_token'] = page_token
|
|
9433
10340
|
if schema_name is not None: query['schema_name'] = schema_name
|
|
9434
10341
|
headers = {'Accept': 'application/json', }
|