collibra-connector 1.0.9__py3-none-any.whl → 1.0.10a0__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.
- collibra_connector/api/Asset.py +189 -19
- collibra_connector/api/Base.py +79 -9
- collibra_connector/api/Comment.py +125 -0
- collibra_connector/api/Community.py +112 -0
- collibra_connector/api/Domain.py +116 -0
- collibra_connector/api/Exceptions.py +0 -5
- collibra_connector/api/Metadata.py +120 -0
- collibra_connector/api/Responsibility.py +303 -0
- collibra_connector/api/User.py +203 -0
- collibra_connector/api/Workflow.py +260 -0
- collibra_connector/api/__init__.py +14 -0
- collibra_connector/connector.py +20 -1
- collibra_connector-1.0.10a0.dist-info/METADATA +157 -0
- collibra_connector-1.0.10a0.dist-info/RECORD +18 -0
- collibra_connector-1.0.9.dist-info/METADATA +0 -27
- collibra_connector-1.0.9.dist-info/RECORD +0 -11
- {collibra_connector-1.0.9.dist-info → collibra_connector-1.0.10a0.dist-info}/WHEEL +0 -0
- {collibra_connector-1.0.9.dist-info → collibra_connector-1.0.10a0.dist-info}/licenses/LICENSE +0 -0
- {collibra_connector-1.0.9.dist-info → collibra_connector-1.0.10a0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
from .Base import BaseAPI
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Domain(BaseAPI):
|
|
6
|
+
def __init__(self, connector):
|
|
7
|
+
super().__init__(connector)
|
|
8
|
+
self.__base_api = connector.api + "/domains"
|
|
9
|
+
|
|
10
|
+
def get_domain(self, domain_id: str):
|
|
11
|
+
"""
|
|
12
|
+
Get a domain by its ID.
|
|
13
|
+
:param domain_id: The ID of the domain to retrieve.
|
|
14
|
+
:return: Domain details.
|
|
15
|
+
"""
|
|
16
|
+
if not domain_id:
|
|
17
|
+
raise ValueError("domain_id is required")
|
|
18
|
+
if not isinstance(domain_id, str):
|
|
19
|
+
raise ValueError("domain_id must be a string")
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
uuid.UUID(domain_id)
|
|
23
|
+
except ValueError as exc:
|
|
24
|
+
raise ValueError("domain_id must be a valid UUID") from exc
|
|
25
|
+
|
|
26
|
+
response = self._get(url=f"{self.__base_api}/{domain_id}")
|
|
27
|
+
return self._handle_response(response)
|
|
28
|
+
|
|
29
|
+
def find_domains(
|
|
30
|
+
self,
|
|
31
|
+
community_id: str = None,
|
|
32
|
+
count_limit: int = -1,
|
|
33
|
+
cursor: str = None,
|
|
34
|
+
exclude_meta: bool = True,
|
|
35
|
+
include_sub_communities: bool = False,
|
|
36
|
+
limit: int = 0,
|
|
37
|
+
name: str = None,
|
|
38
|
+
name_match_mode: str = "ANYWHERE",
|
|
39
|
+
offset: int = 0,
|
|
40
|
+
type_id: str = None,
|
|
41
|
+
type_public_id: str = None
|
|
42
|
+
):
|
|
43
|
+
"""
|
|
44
|
+
Find domains matching the given search criteria.
|
|
45
|
+
:param community_id: ID of the community to find domains in.
|
|
46
|
+
:param count_limit: Limit elements counted. -1 counts all, 0 skips count. Ignored with cursor pagination.
|
|
47
|
+
:param cursor: Cursor for pagination. Pass empty string for first page, use nextCursor for subsequent pages.
|
|
48
|
+
:param exclude_meta: Whether to exclude meta domains (not manually created by users).
|
|
49
|
+
:param include_sub_communities: Whether to search in sub-communities of the specified community.
|
|
50
|
+
:param limit: Maximum results to retrieve. 0 uses default, max 1000.
|
|
51
|
+
:param name: Name of domain to search for.
|
|
52
|
+
:param name_match_mode: Name matching mode. Options: START, END, ANYWHERE, EXACT
|
|
53
|
+
:param offset: First result to retrieve (deprecated, use cursor instead).
|
|
54
|
+
:param type_id: Domain type ID to filter by.
|
|
55
|
+
:param type_public_id: Domain type public ID to filter by.
|
|
56
|
+
:return: List of domains matching criteria.
|
|
57
|
+
"""
|
|
58
|
+
# Validate name_match_mode
|
|
59
|
+
valid_match_modes = ["START", "END", "ANYWHERE", "EXACT"]
|
|
60
|
+
if name_match_mode not in valid_match_modes:
|
|
61
|
+
raise ValueError(f"name_match_mode must be one of: {', '.join(valid_match_modes)}")
|
|
62
|
+
|
|
63
|
+
# Validate limit
|
|
64
|
+
if limit < 0 or limit > 1000:
|
|
65
|
+
raise ValueError("limit must be between 0 and 1000")
|
|
66
|
+
|
|
67
|
+
# Validate community_id if provided
|
|
68
|
+
if community_id is not None:
|
|
69
|
+
if not isinstance(community_id, str):
|
|
70
|
+
raise ValueError("community_id must be a string")
|
|
71
|
+
try:
|
|
72
|
+
uuid.UUID(community_id)
|
|
73
|
+
except ValueError as exc:
|
|
74
|
+
raise ValueError("community_id must be a valid UUID") from exc
|
|
75
|
+
|
|
76
|
+
# Validate type_id if provided
|
|
77
|
+
if type_id is not None:
|
|
78
|
+
if not isinstance(type_id, str):
|
|
79
|
+
raise ValueError("type_id must be a string")
|
|
80
|
+
try:
|
|
81
|
+
uuid.UUID(type_id)
|
|
82
|
+
except ValueError as exc:
|
|
83
|
+
raise ValueError("type_id must be a valid UUID") from exc
|
|
84
|
+
|
|
85
|
+
# Validate cursor and offset usage
|
|
86
|
+
if cursor is not None and offset != 0:
|
|
87
|
+
raise ValueError("Cannot use both cursor and offset in the same request")
|
|
88
|
+
|
|
89
|
+
# Build parameters - only include non-default values
|
|
90
|
+
params = {}
|
|
91
|
+
|
|
92
|
+
if community_id is not None:
|
|
93
|
+
params["communityId"] = community_id
|
|
94
|
+
if count_limit != -1:
|
|
95
|
+
params["countLimit"] = count_limit
|
|
96
|
+
if cursor is not None:
|
|
97
|
+
params["cursor"] = cursor
|
|
98
|
+
if exclude_meta is not True:
|
|
99
|
+
params["excludeMeta"] = exclude_meta
|
|
100
|
+
if include_sub_communities is not False:
|
|
101
|
+
params["includeSubCommunities"] = include_sub_communities
|
|
102
|
+
if limit != 0:
|
|
103
|
+
params["limit"] = limit
|
|
104
|
+
if name is not None:
|
|
105
|
+
params["name"] = name
|
|
106
|
+
if name_match_mode != "ANYWHERE":
|
|
107
|
+
params["nameMatchMode"] = name_match_mode
|
|
108
|
+
if offset != 0:
|
|
109
|
+
params["offset"] = offset
|
|
110
|
+
if type_id is not None:
|
|
111
|
+
params["typeId"] = type_id
|
|
112
|
+
if type_public_id is not None:
|
|
113
|
+
params["typePublicId"] = type_public_id
|
|
114
|
+
|
|
115
|
+
response = self._get(params=params)
|
|
116
|
+
return self._handle_response(response)
|
|
@@ -1,24 +1,19 @@
|
|
|
1
1
|
|
|
2
2
|
class CollibraAPIError(Exception):
|
|
3
3
|
"""Base exception for Collibra API errors"""
|
|
4
|
-
pass
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
class UnauthorizedError(CollibraAPIError):
|
|
8
7
|
"""Raised when authentication fails"""
|
|
9
|
-
pass
|
|
10
8
|
|
|
11
9
|
|
|
12
10
|
class ForbiddenError(CollibraAPIError):
|
|
13
11
|
"""Raised when access is forbidden"""
|
|
14
|
-
pass
|
|
15
12
|
|
|
16
13
|
|
|
17
14
|
class NotFoundError(CollibraAPIError):
|
|
18
15
|
"""Raised when resource is not found"""
|
|
19
|
-
pass
|
|
20
16
|
|
|
21
17
|
|
|
22
18
|
class ServerError(CollibraAPIError):
|
|
23
19
|
"""Raised when server returns 5xx errors"""
|
|
24
|
-
pass
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
from .Base import BaseAPI
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Metadata(BaseAPI):
|
|
5
|
+
def __init__(self, connector):
|
|
6
|
+
super().__init__(connector)
|
|
7
|
+
self.__base_api = connector.api
|
|
8
|
+
|
|
9
|
+
def get_collibra_metadata(self):
|
|
10
|
+
"""
|
|
11
|
+
Retrieve comprehensive metadata from Collibra including asset types,
|
|
12
|
+
relation types, responsibilities, statuses, attributes, communities,
|
|
13
|
+
domains, and domain types.
|
|
14
|
+
:return: Dictionary containing all metadata with names as keys and UUIDs as values.
|
|
15
|
+
"""
|
|
16
|
+
metadata = {
|
|
17
|
+
"AssetType": {},
|
|
18
|
+
"Relation": {},
|
|
19
|
+
"Responsibility": {},
|
|
20
|
+
"Status": {},
|
|
21
|
+
"StringAttribute": {},
|
|
22
|
+
"Community": {},
|
|
23
|
+
"Domain": {},
|
|
24
|
+
"DomainType": {},
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
try:
|
|
28
|
+
# Get Asset Types
|
|
29
|
+
asset_types_response = self._get(url=f"{self.__base_api}/assetTypes")
|
|
30
|
+
asset_types_data = self._handle_response(asset_types_response)
|
|
31
|
+
for asset_type in asset_types_data.get("results", []):
|
|
32
|
+
metadata["AssetType"][asset_type["name"]] = asset_type["id"]
|
|
33
|
+
|
|
34
|
+
# Get Relation Types
|
|
35
|
+
relation_types_response = self._get(url=f"{self.__base_api}/relationTypes")
|
|
36
|
+
relation_types_data = self._handle_response(relation_types_response)
|
|
37
|
+
for relation_type in relation_types_data.get("results", []):
|
|
38
|
+
import re
|
|
39
|
+
source_name = re.sub(" ", "", relation_type["sourceType"]["name"])
|
|
40
|
+
target_name = re.sub(" ", "", relation_type["targetType"]["name"])
|
|
41
|
+
metadata["Relation"][f"{source_name}_{target_name}"] = relation_type["id"]
|
|
42
|
+
|
|
43
|
+
# Get Roles/Responsibilities
|
|
44
|
+
roles_response = self._get(url=f"{self.__base_api}/roles")
|
|
45
|
+
roles_data = self._handle_response(roles_response)
|
|
46
|
+
for role in roles_data.get("results", []):
|
|
47
|
+
metadata["Responsibility"][role["name"]] = role["id"]
|
|
48
|
+
|
|
49
|
+
# Get Statuses
|
|
50
|
+
statuses_response = self._get(url=f"{self.__base_api}/statuses")
|
|
51
|
+
statuses_data = self._handle_response(statuses_response)
|
|
52
|
+
for status in statuses_data.get("results", []):
|
|
53
|
+
metadata["Status"][status["name"]] = status["id"]
|
|
54
|
+
|
|
55
|
+
# Get Attribute Types
|
|
56
|
+
attributes_response = self._get(url=f"{self.__base_api}/attributeTypes")
|
|
57
|
+
attributes_data = self._handle_response(attributes_response)
|
|
58
|
+
for attribute in attributes_data.get("results", []):
|
|
59
|
+
metadata["StringAttribute"][attribute["name"]] = attribute["id"]
|
|
60
|
+
|
|
61
|
+
# Get Communities
|
|
62
|
+
communities_response = self._get(url=f"{self.__base_api}/communities")
|
|
63
|
+
communities_data = self._handle_response(communities_response)
|
|
64
|
+
for community in communities_data.get("results", []):
|
|
65
|
+
metadata["Community"][community["name"]] = community["id"]
|
|
66
|
+
|
|
67
|
+
# Get Domains (with pagination)
|
|
68
|
+
domains_params = {"limit": 1000, "offset": 0}
|
|
69
|
+
while True:
|
|
70
|
+
domains_response = self._get(url=f"{self.__base_api}/domains", params=domains_params)
|
|
71
|
+
domains_data = self._handle_response(domains_response)
|
|
72
|
+
for domain in domains_data.get("results", []):
|
|
73
|
+
metadata["Domain"][domain["name"]] = domain["id"]
|
|
74
|
+
if (
|
|
75
|
+
domains_data.get("offset", 0) + domains_data.get("limit", 0) >=
|
|
76
|
+
domains_data.get("total", 0)
|
|
77
|
+
):
|
|
78
|
+
break
|
|
79
|
+
domains_params["offset"] += domains_params["limit"]
|
|
80
|
+
|
|
81
|
+
# Get Domain Types
|
|
82
|
+
domain_types_response = self._get(url=f"{self.__base_api}/domainTypes")
|
|
83
|
+
domain_types_data = self._handle_response(domain_types_response)
|
|
84
|
+
for domain_type in domain_types_data.get("results", []):
|
|
85
|
+
metadata["DomainType"][domain_type["name"]] = domain_type["id"]
|
|
86
|
+
|
|
87
|
+
return metadata
|
|
88
|
+
|
|
89
|
+
except Exception as e:
|
|
90
|
+
raise Exception(f"Error fetching Collibra metadata: {str(e)}") from e
|
|
91
|
+
|
|
92
|
+
def get_asset_types(self):
|
|
93
|
+
"""Get all asset types."""
|
|
94
|
+
response = self._get(url=f"{self.__base_api}/assetTypes")
|
|
95
|
+
return self._handle_response(response)
|
|
96
|
+
|
|
97
|
+
def get_relation_types(self):
|
|
98
|
+
"""Get all relation types."""
|
|
99
|
+
response = self._get(url=f"{self.__base_api}/relationTypes")
|
|
100
|
+
return self._handle_response(response)
|
|
101
|
+
|
|
102
|
+
def get_statuses(self):
|
|
103
|
+
"""Get all statuses."""
|
|
104
|
+
response = self._get(url=f"{self.__base_api}/statuses")
|
|
105
|
+
return self._handle_response(response)
|
|
106
|
+
|
|
107
|
+
def get_attribute_types(self):
|
|
108
|
+
"""Get all attribute types."""
|
|
109
|
+
response = self._get(url=f"{self.__base_api}/attributeTypes")
|
|
110
|
+
return self._handle_response(response)
|
|
111
|
+
|
|
112
|
+
def get_domain_types(self):
|
|
113
|
+
"""Get all domain types."""
|
|
114
|
+
response = self._get(url=f"{self.__base_api}/domainTypes")
|
|
115
|
+
return self._handle_response(response)
|
|
116
|
+
|
|
117
|
+
def get_roles(self):
|
|
118
|
+
"""Get all roles."""
|
|
119
|
+
response = self._get(url=f"{self.__base_api}/roles")
|
|
120
|
+
return self._handle_response(response)
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
from .Base import BaseAPI
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Responsibility(BaseAPI):
|
|
6
|
+
def __init__(self, connector):
|
|
7
|
+
super().__init__(connector)
|
|
8
|
+
self.__base_api = connector.api + "/responsibilities"
|
|
9
|
+
|
|
10
|
+
def add_responsibility(
|
|
11
|
+
self,
|
|
12
|
+
role_id: str,
|
|
13
|
+
owner_id: str,
|
|
14
|
+
resource_id: str = None,
|
|
15
|
+
resource_type: str = None,
|
|
16
|
+
resource_discriminator: str = None
|
|
17
|
+
):
|
|
18
|
+
"""
|
|
19
|
+
Add a new responsibility. Assigns given user to resource with given role.
|
|
20
|
+
:param role_id: The ID of the role that should be assigned to user.
|
|
21
|
+
:param owner_id: The ID of the user who the responsibility is created for.
|
|
22
|
+
:param resource_id: The ID of the resource which the responsibility is created for.
|
|
23
|
+
If None, creates global responsibility.
|
|
24
|
+
:param resource_type: The type of the resource (e.g., Asset, Community, Domain, etc.).
|
|
25
|
+
:param resource_discriminator: The discriminator for resource type. Valid values: "Community", "Domain", "Asset"
|
|
26
|
+
:return: The responsibility ID.
|
|
27
|
+
"""
|
|
28
|
+
# Validate required parameters
|
|
29
|
+
if not role_id or not owner_id:
|
|
30
|
+
raise ValueError("role_id and owner_id are required parameters")
|
|
31
|
+
|
|
32
|
+
# Validate UUIDs
|
|
33
|
+
for param_name, param_value in [("role_id", role_id), ("owner_id", owner_id)]:
|
|
34
|
+
if not isinstance(param_value, str):
|
|
35
|
+
raise ValueError(f"{param_name} must be a string")
|
|
36
|
+
try:
|
|
37
|
+
uuid.UUID(param_value)
|
|
38
|
+
except ValueError as exc:
|
|
39
|
+
raise ValueError(f"{param_name} must be a valid UUID") from exc
|
|
40
|
+
|
|
41
|
+
# Validate resource_id if provided
|
|
42
|
+
if resource_id is not None:
|
|
43
|
+
if not isinstance(resource_id, str):
|
|
44
|
+
raise ValueError("resource_id must be a string")
|
|
45
|
+
try:
|
|
46
|
+
uuid.UUID(resource_id)
|
|
47
|
+
except ValueError as exc:
|
|
48
|
+
raise ValueError("resource_id must be a valid UUID") from exc
|
|
49
|
+
|
|
50
|
+
# Validate resource_type if provided
|
|
51
|
+
valid_resource_types = [
|
|
52
|
+
"View", "Asset", "Community", "Domain", "AssetType", "DomainType", "Status", "User",
|
|
53
|
+
"Classification", "MatchUser", "Group", "Attribute", "StringAttribute", "ScriptAttribute",
|
|
54
|
+
"BooleanAttribute", "DateAttribute", "NumericAttribute", "SingleValueListAttribute",
|
|
55
|
+
"MultiValueListAttribute", "Comment", "Attachment", "Responsibility", "Workflow", "Job",
|
|
56
|
+
"Relation", "RelationType", "ComplexRelation", "ComplexRelationType", "ArticulationRule",
|
|
57
|
+
"Assignment", "ScopeRelation", "Trace", "ValidationRule", "DataQualityRule", "DataQualityMetric",
|
|
58
|
+
"Address", "InstantMessagingAccount", "Email", "PhoneNumber", "Website", "Activity",
|
|
59
|
+
"FormProperty", "WorkflowTask", "ActivityChange", "WorkflowInstance", "Role", "AttributeType",
|
|
60
|
+
"BooleanAttributeType", "DateAttributeType", "DateTimeAttributeType", "MultiValueListAttributeType",
|
|
61
|
+
"NumericAttributeType", "ScriptAttributeType", "SingleValueListAttributeType", "StringAttributeType",
|
|
62
|
+
"ViewSharingRule", "ViewAssignmentRule", "JdbcDriver", "File", "JdbcDriverJdbcIngestionProperties",
|
|
63
|
+
"CsvIngestionProperties", "ExcelIngestionProperties", "ConnectionStringParameter",
|
|
64
|
+
"AssignedCharacteristicType", "Notification", "Tag", "ComplexRelationLegType",
|
|
65
|
+
"ComplexRelationAttributeType", "ComplexRelationLeg", "BaseDataType", "AdvancedDataType",
|
|
66
|
+
"Diagram", "Picture", "DiagramPictureSharingRule", "DiagramPictureAssignmentRule", "Rating",
|
|
67
|
+
"ClassificationPhysicalData", "ConnectorContext"
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
if resource_type is not None and resource_type not in valid_resource_types:
|
|
71
|
+
raise ValueError(
|
|
72
|
+
"resource_type must be one of the valid resource types. See API documentation for full list."
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# Validate resource_discriminator if provided
|
|
76
|
+
valid_discriminators = ["Community", "Domain", "Asset"]
|
|
77
|
+
if resource_discriminator is not None and resource_discriminator not in valid_discriminators:
|
|
78
|
+
raise ValueError(f"resource_discriminator must be one of: {', '.join(valid_discriminators)}")
|
|
79
|
+
|
|
80
|
+
# Build request data - only include non-None values
|
|
81
|
+
data = {
|
|
82
|
+
"roleId": role_id,
|
|
83
|
+
"ownerId": owner_id
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if resource_id is not None:
|
|
87
|
+
data["resourceId"] = resource_id
|
|
88
|
+
if resource_type is not None:
|
|
89
|
+
data["resourceType"] = resource_type
|
|
90
|
+
if resource_discriminator is not None:
|
|
91
|
+
data["resourceDiscriminator"] = resource_discriminator
|
|
92
|
+
|
|
93
|
+
response = self._post(url=self.__base_api, data=data)
|
|
94
|
+
result = self._handle_response(response)
|
|
95
|
+
return result.get("id")
|
|
96
|
+
|
|
97
|
+
def get_responsibility(self, responsibility_id: str):
|
|
98
|
+
"""
|
|
99
|
+
Get details of a specific responsibility.
|
|
100
|
+
:param responsibility_id: The ID of the responsibility.
|
|
101
|
+
:return: Responsibility details.
|
|
102
|
+
"""
|
|
103
|
+
if not responsibility_id:
|
|
104
|
+
raise ValueError("responsibility_id is required")
|
|
105
|
+
if not isinstance(responsibility_id, str):
|
|
106
|
+
raise ValueError("responsibility_id must be a string")
|
|
107
|
+
|
|
108
|
+
try:
|
|
109
|
+
uuid.UUID(responsibility_id)
|
|
110
|
+
except ValueError as exc:
|
|
111
|
+
raise ValueError("responsibility_id must be a valid UUID") from exc
|
|
112
|
+
|
|
113
|
+
response = self._get(url=f"{self.__base_api}/{responsibility_id}")
|
|
114
|
+
return self._handle_response(response)
|
|
115
|
+
|
|
116
|
+
def find_responsibilities(
|
|
117
|
+
self,
|
|
118
|
+
count_limit: int = -1,
|
|
119
|
+
exclude_empty_groups: bool = None,
|
|
120
|
+
global_only: bool = None,
|
|
121
|
+
include_inherited: bool = True,
|
|
122
|
+
limit: int = 0,
|
|
123
|
+
offset: int = 0,
|
|
124
|
+
owner_ids: list = None,
|
|
125
|
+
resource_ids: list = None,
|
|
126
|
+
role_ids: list = None,
|
|
127
|
+
sort_field: str = "LAST_MODIFIED",
|
|
128
|
+
sort_order: str = "DESC",
|
|
129
|
+
_type: str = None
|
|
130
|
+
):
|
|
131
|
+
"""
|
|
132
|
+
Find responsibilities matching the given search criteria.
|
|
133
|
+
:param count_limit: Limit the number of elements counted. -1 counts everything, 0 skips count.
|
|
134
|
+
:param exclude_empty_groups: Whether responsibilities assigned to empty groups should be excluded.
|
|
135
|
+
:param global_only: Whether only global responsibilities should be searched (deprecated).
|
|
136
|
+
:param include_inherited: Whether inherited responsibilities should be included.
|
|
137
|
+
:param limit: Maximum number of results to retrieve. 0 uses default, max 1000.
|
|
138
|
+
:param offset: First result to retrieve. 0 starts from beginning.
|
|
139
|
+
:param owner_ids: List of owner IDs to filter responsibilities by.
|
|
140
|
+
:param resource_ids: List of resource IDs to filter responsibilities by.
|
|
141
|
+
:param role_ids: List of role IDs to filter responsibilities by.
|
|
142
|
+
:param sort_field: Field to sort results by. Options: CREATED_BY, CREATED_ON, LAST_MODIFIED, NAME
|
|
143
|
+
:param sort_order: Sort order. Options: ASC, DESC
|
|
144
|
+
:param type: Type of responsibilities. Options: ALL, GLOBAL, RESOURCE
|
|
145
|
+
:return: List of responsibilities matching the criteria.
|
|
146
|
+
"""
|
|
147
|
+
# Validate sort_field
|
|
148
|
+
valid_sort_fields = ["CREATED_BY", "CREATED_ON", "LAST_MODIFIED", "NAME"]
|
|
149
|
+
if sort_field not in valid_sort_fields:
|
|
150
|
+
raise ValueError(f"sort_field must be one of: {', '.join(valid_sort_fields)}")
|
|
151
|
+
|
|
152
|
+
# Validate sort_order
|
|
153
|
+
if sort_order not in ["ASC", "DESC"]:
|
|
154
|
+
raise ValueError("sort_order must be 'ASC' or 'DESC'")
|
|
155
|
+
|
|
156
|
+
# Validate limit
|
|
157
|
+
if limit < 0 or limit > 1000:
|
|
158
|
+
raise ValueError("limit must be between 0 and 1000")
|
|
159
|
+
|
|
160
|
+
# Validate type if provided
|
|
161
|
+
valid_types = ["ALL", "GLOBAL", "RESOURCE"]
|
|
162
|
+
if _type is not None and _type not in valid_types:
|
|
163
|
+
raise ValueError(f"type must be one of: {', '.join(valid_types)}")
|
|
164
|
+
|
|
165
|
+
# Validate that globalOnly and type are mutually exclusive
|
|
166
|
+
if global_only is not None and type is not None:
|
|
167
|
+
raise ValueError("globalOnly and type parameters are mutually exclusive")
|
|
168
|
+
|
|
169
|
+
# Validate owner_ids if provided
|
|
170
|
+
if owner_ids is not None:
|
|
171
|
+
if not isinstance(owner_ids, list):
|
|
172
|
+
raise ValueError("owner_ids must be a list")
|
|
173
|
+
for owner_id in owner_ids:
|
|
174
|
+
if not isinstance(owner_id, str):
|
|
175
|
+
raise ValueError("owner_id must be a string")
|
|
176
|
+
try:
|
|
177
|
+
uuid.UUID(owner_id)
|
|
178
|
+
except ValueError as exc:
|
|
179
|
+
raise ValueError("owner_id must be a valid UUID") from exc
|
|
180
|
+
|
|
181
|
+
# Validate resource_ids if provided
|
|
182
|
+
if resource_ids is not None:
|
|
183
|
+
if not isinstance(resource_ids, list):
|
|
184
|
+
raise ValueError("resource_ids must be a list")
|
|
185
|
+
for resource_id in resource_ids:
|
|
186
|
+
if not isinstance(resource_id, str):
|
|
187
|
+
raise ValueError("resource_id must be a string")
|
|
188
|
+
try:
|
|
189
|
+
uuid.UUID(resource_id)
|
|
190
|
+
except ValueError as exc:
|
|
191
|
+
raise ValueError("resource_id must be a valid UUID") from exc
|
|
192
|
+
|
|
193
|
+
# Validate role_ids if provided
|
|
194
|
+
if role_ids is not None:
|
|
195
|
+
if not isinstance(role_ids, list):
|
|
196
|
+
raise ValueError("role_ids must be a list")
|
|
197
|
+
for role_id in role_ids:
|
|
198
|
+
if not isinstance(role_id, str):
|
|
199
|
+
raise ValueError("role_id must be a string")
|
|
200
|
+
try:
|
|
201
|
+
uuid.UUID(role_id)
|
|
202
|
+
except ValueError as exc:
|
|
203
|
+
raise ValueError("role_id must be a valid UUID") from exc
|
|
204
|
+
|
|
205
|
+
# Build parameters - only include non-default values
|
|
206
|
+
params = {}
|
|
207
|
+
|
|
208
|
+
if count_limit != -1:
|
|
209
|
+
params["countLimit"] = count_limit
|
|
210
|
+
if exclude_empty_groups is not None:
|
|
211
|
+
params["excludeEmptyGroups"] = exclude_empty_groups
|
|
212
|
+
if global_only is not None:
|
|
213
|
+
params["globalOnly"] = global_only
|
|
214
|
+
if include_inherited is not True:
|
|
215
|
+
params["includeInherited"] = include_inherited
|
|
216
|
+
if limit != 0:
|
|
217
|
+
params["limit"] = limit
|
|
218
|
+
if offset != 0:
|
|
219
|
+
params["offset"] = offset
|
|
220
|
+
if owner_ids is not None:
|
|
221
|
+
params["ownerIds"] = owner_ids
|
|
222
|
+
if resource_ids is not None:
|
|
223
|
+
params["resourceIds"] = resource_ids
|
|
224
|
+
if role_ids is not None:
|
|
225
|
+
params["roleIds"] = role_ids
|
|
226
|
+
if sort_field != "LAST_MODIFIED":
|
|
227
|
+
params["sortField"] = sort_field
|
|
228
|
+
if sort_order != "DESC":
|
|
229
|
+
params["sortOrder"] = sort_order
|
|
230
|
+
if type is not None:
|
|
231
|
+
params["type"] = type
|
|
232
|
+
|
|
233
|
+
response = self._get(params=params)
|
|
234
|
+
return self._handle_response(response)
|
|
235
|
+
|
|
236
|
+
def get_asset_responsibilities(self, asset_id: str, role_ids: list = None):
|
|
237
|
+
"""
|
|
238
|
+
Get responsibilities for an asset (convenience method).
|
|
239
|
+
:param asset_id: The ID of the asset.
|
|
240
|
+
:param role_ids: Optional list of role IDs to filter by.
|
|
241
|
+
:return: List of responsibilities.
|
|
242
|
+
"""
|
|
243
|
+
if not asset_id:
|
|
244
|
+
raise ValueError("asset_id is required")
|
|
245
|
+
if not isinstance(asset_id, str):
|
|
246
|
+
raise ValueError("asset_id must be a string")
|
|
247
|
+
|
|
248
|
+
try:
|
|
249
|
+
uuid.UUID(asset_id)
|
|
250
|
+
except ValueError as exc:
|
|
251
|
+
raise ValueError("asset_id must be a valid UUID") from exc
|
|
252
|
+
|
|
253
|
+
return self.find_responsibilities(
|
|
254
|
+
resource_ids=[asset_id],
|
|
255
|
+
role_ids=role_ids
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
def get_user_responsibilities(self, user_id: str, role_id: str = None):
|
|
259
|
+
"""
|
|
260
|
+
Get responsibilities for a user (convenience method).
|
|
261
|
+
:param user_id: The ID of the user.
|
|
262
|
+
:param role_id: Optional role ID to filter by.
|
|
263
|
+
:return: List of responsibilities.
|
|
264
|
+
"""
|
|
265
|
+
if not user_id:
|
|
266
|
+
raise ValueError("user_id is required")
|
|
267
|
+
if not isinstance(user_id, str):
|
|
268
|
+
raise ValueError("user_id must be a string")
|
|
269
|
+
|
|
270
|
+
try:
|
|
271
|
+
uuid.UUID(user_id)
|
|
272
|
+
except ValueError as exc:
|
|
273
|
+
raise ValueError("user_id must be a valid UUID") from exc
|
|
274
|
+
|
|
275
|
+
role_ids = [role_id] if role_id else None
|
|
276
|
+
return self.find_responsibilities(
|
|
277
|
+
owner_ids=[user_id],
|
|
278
|
+
role_ids=role_ids
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
def get_global_responsibilities(self, role_ids: list = None):
|
|
282
|
+
"""
|
|
283
|
+
Get global responsibilities (convenience method).
|
|
284
|
+
:param role_ids: Optional list of role IDs to filter by.
|
|
285
|
+
:return: List of global responsibilities.
|
|
286
|
+
"""
|
|
287
|
+
return self.find_responsibilities(
|
|
288
|
+
_type="GLOBAL",
|
|
289
|
+
role_ids=role_ids
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
def get_resource_responsibilities(self, resource_ids: list = None, role_ids: list = None):
|
|
293
|
+
"""
|
|
294
|
+
Get resource-specific responsibilities (convenience method).
|
|
295
|
+
:param resource_ids: Optional list of resource IDs to filter by.
|
|
296
|
+
:param role_ids: Optional list of role IDs to filter by.
|
|
297
|
+
:return: List of resource responsibilities.
|
|
298
|
+
"""
|
|
299
|
+
return self.find_responsibilities(
|
|
300
|
+
_type="RESOURCE",
|
|
301
|
+
resource_ids=resource_ids,
|
|
302
|
+
role_ids=role_ids
|
|
303
|
+
)
|