11import json
2+ from dataclasses import asdict , dataclass
23
34import pandas as pd
45from databricks .sdk .service .iam import ObjectPermissions
56from databricks .sdk .service .workspace import AclItem as SdkAclItem
67from databricks .sdk .service .workspace import AclPermission as SdkAclPermission
7- from pydantic import BaseModel
8- from pydantic .tools import parse_obj_as
98
109from databricks .labs .ucx .generic import StrEnum
1110
@@ -30,16 +29,6 @@ def __repr__(self):
3029 return self .value
3130
3231
33- class SqlRequestObjectType (StrEnum ):
34- ALERTS = "alerts"
35- DASHBOARDS = "dashboards"
36- DATA_SOURCES = "data-sources"
37- QUERIES = "queries"
38-
39- def __repr__ (self ):
40- return self .value
41-
42-
4332class LogicalObjectType (StrEnum ):
4433 ENTITLEMENTS = "ENTITLEMENTS"
4534 ROLES = "ROLES"
@@ -69,12 +58,18 @@ class AclPermission(StrEnum):
6958 MANAGE = "MANAGE"
7059
7160
72- class AclItem (BaseModel ):
61+ @dataclass
62+ class AclItem :
7363 principal : str
7464 permission : AclPermission
7565
66+ @classmethod
67+ def from_dict (cls , raw : dict ):
68+ return cls (principal = raw .get ("principal" , None ), permission = AclPermission (raw .get ("permission" )))
69+
7670
77- class AclItemsContainer (BaseModel ):
71+ @dataclass
72+ class AclItemsContainer :
7873 acls : list [AclItem ]
7974
8075 @staticmethod
@@ -89,16 +84,25 @@ def to_sdk(self) -> list[SdkAclItem]:
8984 SdkAclItem (principal = acl .principal , permission = SdkAclPermission (acl .permission .value )) for acl in self .acls
9085 ]
9186
87+ @classmethod
88+ def from_dict (cls , raw : dict ) -> "AclItemsContainer" :
89+ return cls (acls = [AclItem .from_dict (a ) for a in raw .get ("acls" , [])])
90+
91+ def as_dict (self ) -> dict :
92+ return asdict (self )
93+
9294
93- class RolesAndEntitlements (BaseModel ):
95+ @dataclass
96+ class RolesAndEntitlements :
9497 roles : list
9598 entitlements : list
9699
97100
98- class PermissionsInventoryItem (BaseModel ):
101+ @dataclass
102+ class PermissionsInventoryItem :
99103 object_id : str
100104 logical_object_type : LogicalObjectType
101- request_object_type : RequestObjectType | SqlRequestObjectType | None
105+ request_object_type : RequestObjectType | None
102106 raw_object_permissions : str
103107
104108 @property
@@ -108,13 +112,27 @@ def object_permissions(self) -> dict:
108112 @property
109113 def typed_object_permissions (self ) -> ObjectPermissions | AclItemsContainer | RolesAndEntitlements :
110114 if self .logical_object_type == LogicalObjectType .SECRET_SCOPE :
111- return parse_obj_as ( AclItemsContainer , self .object_permissions )
115+ return AclItemsContainer . from_dict ( self .object_permissions )
112116 elif self .logical_object_type in [LogicalObjectType .ROLES , LogicalObjectType .ENTITLEMENTS ]:
113- return parse_obj_as ( RolesAndEntitlements , self .object_permissions )
117+ return RolesAndEntitlements ( ** self .object_permissions )
114118 else :
115119 return ObjectPermissions .from_dict (self .object_permissions )
116120
117121 @staticmethod
118122 def from_pandas (source : pd .DataFrame ) -> list ["PermissionsInventoryItem" ]:
119123 items = source .to_dict (orient = "records" )
120- return [PermissionsInventoryItem (** item ) for item in items ]
124+ return [PermissionsInventoryItem .from_dict (item ) for item in items ]
125+
126+ def as_dict (self ) -> dict :
127+ return asdict (self )
128+
129+ @classmethod
130+ def from_dict (cls , raw : dict ) -> "PermissionsInventoryItem" :
131+ return cls (
132+ object_id = raw ["object_id" ],
133+ logical_object_type = LogicalObjectType (raw ["logical_object_type" ]),
134+ request_object_type = RequestObjectType (raw ["request_object_type" ])
135+ if raw .get ("request_object_type" , None ) is not None
136+ else None ,
137+ raw_object_permissions = raw .get ("raw_object_permissions" , None ),
138+ )
0 commit comments