gcp-platforms-auto 0.8.3__tar.gz → 0.8.4__tar.gz
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.
- {gcp_platforms_auto-0.8.3 → gcp_platforms_auto-0.8.4}/PKG-INFO +1 -1
- {gcp_platforms_auto-0.8.3 → gcp_platforms_auto-0.8.4}/gcp_platforms_auto/__init__.py +3 -1
- gcp_platforms_auto-0.8.4/gcp_platforms_auto/iam.py +318 -0
- {gcp_platforms_auto-0.8.3 → gcp_platforms_auto-0.8.4}/gcp_platforms_auto.egg-info/PKG-INFO +1 -1
- {gcp_platforms_auto-0.8.3 → gcp_platforms_auto-0.8.4}/pyproject.toml +1 -1
- gcp_platforms_auto-0.8.3/gcp_platforms_auto/iam.py +0 -190
- {gcp_platforms_auto-0.8.3 → gcp_platforms_auto-0.8.4}/README.md +0 -0
- {gcp_platforms_auto-0.8.3 → gcp_platforms_auto-0.8.4}/gcp_platforms_auto/db.py +0 -0
- {gcp_platforms_auto-0.8.3 → gcp_platforms_auto-0.8.4}/gcp_platforms_auto/git.py +0 -0
- {gcp_platforms_auto-0.8.3 → gcp_platforms_auto-0.8.4}/gcp_platforms_auto/models.py +0 -0
- {gcp_platforms_auto-0.8.3 → gcp_platforms_auto-0.8.4}/gcp_platforms_auto.egg-info/SOURCES.txt +0 -0
- {gcp_platforms_auto-0.8.3 → gcp_platforms_auto-0.8.4}/gcp_platforms_auto.egg-info/dependency_links.txt +0 -0
- {gcp_platforms_auto-0.8.3 → gcp_platforms_auto-0.8.4}/gcp_platforms_auto.egg-info/requires.txt +0 -0
- {gcp_platforms_auto-0.8.3 → gcp_platforms_auto-0.8.4}/gcp_platforms_auto.egg-info/top_level.txt +0 -0
- {gcp_platforms_auto-0.8.3 → gcp_platforms_auto-0.8.4}/setup.cfg +0 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
"""IAM access management utilities for GCP."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import os
|
|
5
|
+
import google.cloud.logging
|
|
6
|
+
from google.cloud import asset_v1
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
# Initialize Google Cloud Logging
|
|
10
|
+
client = google.cloud.logging.Client()
|
|
11
|
+
client.setup_logging()
|
|
12
|
+
|
|
13
|
+
# Configure the logger
|
|
14
|
+
logger = logging.getLogger("uvicorn")
|
|
15
|
+
logger.setLevel(logging.INFO)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def check_user_has_role_in_project(
|
|
19
|
+
project_id: str,
|
|
20
|
+
user_email: str,
|
|
21
|
+
organization_id: str,
|
|
22
|
+
role: str = "roles/owner",
|
|
23
|
+
expand_groups: bool = True
|
|
24
|
+
) -> bool:
|
|
25
|
+
"""
|
|
26
|
+
Check if a user has a specific role in a GCP project.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
project_id: GCP project ID (e.g., 'sky-starfi-mam-res-gcpro-1')
|
|
30
|
+
user_email: Email of the user to check (e.g., 'oshasha10@gcporg.com')
|
|
31
|
+
organization_id: GCP organization ID (e.g., '111111111111')
|
|
32
|
+
role: Role to check (e.g., 'roles/owner', 'roles/editor')
|
|
33
|
+
expand_groups: Whether to expand group memberships (default: True)
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
bool: True if the user has the role in the project, False otherwise
|
|
37
|
+
|
|
38
|
+
Example:
|
|
39
|
+
>>> has_access = check_user_has_role_in_project(
|
|
40
|
+
... project_id='sky-starfi-mam-res-gcpro-1',
|
|
41
|
+
... user_email='oshasha10@gcporg.com',
|
|
42
|
+
... organization_id='111111111111',
|
|
43
|
+
... role='roles/owner'
|
|
44
|
+
... )
|
|
45
|
+
"""
|
|
46
|
+
client = asset_v1.AssetServiceClient()
|
|
47
|
+
|
|
48
|
+
# Construct the full resource name
|
|
49
|
+
scope = f"organizations/{organization_id}"
|
|
50
|
+
full_resource_name = f"//cloudresourcemanager.googleapis.com/projects/{project_id}"
|
|
51
|
+
identity = f"user:{user_email}"
|
|
52
|
+
|
|
53
|
+
# Build the request
|
|
54
|
+
request = asset_v1.AnalyzeIamPolicyRequest(
|
|
55
|
+
analysis_query=asset_v1.IamPolicyAnalysisQuery(
|
|
56
|
+
scope=scope,
|
|
57
|
+
resource_selector=asset_v1.IamPolicyAnalysisQuery.ResourceSelector(
|
|
58
|
+
full_resource_name=full_resource_name
|
|
59
|
+
),
|
|
60
|
+
identity_selector=asset_v1.IamPolicyAnalysisQuery.IdentitySelector(
|
|
61
|
+
identity=identity
|
|
62
|
+
),
|
|
63
|
+
access_selector=asset_v1.IamPolicyAnalysisQuery.AccessSelector(
|
|
64
|
+
roles=[role]
|
|
65
|
+
),
|
|
66
|
+
options=asset_v1.IamPolicyAnalysisQuery.Options(
|
|
67
|
+
expand_groups=expand_groups,
|
|
68
|
+
expand_roles=True,
|
|
69
|
+
)
|
|
70
|
+
)
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
try:
|
|
74
|
+
# Execute the analysis
|
|
75
|
+
logger.info(f"Checking if user {user_email} has role {role} in project {project_id}")
|
|
76
|
+
response = client.analyze_iam_policy(request=request)
|
|
77
|
+
|
|
78
|
+
# Check if any results were returned
|
|
79
|
+
if response.main_analysis and response.main_analysis.analysis_results:
|
|
80
|
+
logger.info(f"User {user_email} has role {role} in project {project_id}")
|
|
81
|
+
return True
|
|
82
|
+
|
|
83
|
+
logger.info(f"User {user_email} does not have role {role} in project {project_id}")
|
|
84
|
+
return False
|
|
85
|
+
|
|
86
|
+
except Exception as e:
|
|
87
|
+
logger.exception(f"Error analyzing IAM policy: {e}")
|
|
88
|
+
raise
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def check_service_account_has_role_in_project(
|
|
92
|
+
project_id: str,
|
|
93
|
+
service_account_email: str,
|
|
94
|
+
organization_id: str,
|
|
95
|
+
role: str = "roles/owner",
|
|
96
|
+
expand_groups: bool = True
|
|
97
|
+
) -> bool:
|
|
98
|
+
"""
|
|
99
|
+
Check if a service account has a specific role in a GCP project.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
project_id: GCP project ID (e.g., 'sky-starfi-mam-res-gcpro-1')
|
|
103
|
+
service_account_email: Email of the service account to check
|
|
104
|
+
(e.g., 'my-sa@project.iam.gserviceaccount.com')
|
|
105
|
+
organization_id: GCP organization ID (e.g., '111111111111')
|
|
106
|
+
role: Role to check (e.g., 'roles/owner', 'roles/editor')
|
|
107
|
+
expand_groups: Whether to expand group memberships (default: True)
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
bool: True if the service account has the role in the project, False otherwise
|
|
111
|
+
|
|
112
|
+
Example:
|
|
113
|
+
>>> has_access = check_service_account_has_role_in_project(
|
|
114
|
+
... project_id='sky-starfi-mam-res-gcpro-1',
|
|
115
|
+
... service_account_email='my-sa@project.iam.gserviceaccount.com',
|
|
116
|
+
... organization_id='111111111111',
|
|
117
|
+
... role='roles/owner'
|
|
118
|
+
... )
|
|
119
|
+
"""
|
|
120
|
+
client = asset_v1.AssetServiceClient()
|
|
121
|
+
|
|
122
|
+
# Construct the full resource name
|
|
123
|
+
scope = f"organizations/{organization_id}"
|
|
124
|
+
full_resource_name = f"//cloudresourcemanager.googleapis.com/projects/{project_id}"
|
|
125
|
+
identity = f"serviceAccount:{service_account_email}"
|
|
126
|
+
|
|
127
|
+
# Build the request
|
|
128
|
+
request = asset_v1.AnalyzeIamPolicyRequest(
|
|
129
|
+
analysis_query=asset_v1.IamPolicyAnalysisQuery(
|
|
130
|
+
scope=scope,
|
|
131
|
+
resource_selector=asset_v1.IamPolicyAnalysisQuery.ResourceSelector(
|
|
132
|
+
full_resource_name=full_resource_name
|
|
133
|
+
),
|
|
134
|
+
identity_selector=asset_v1.IamPolicyAnalysisQuery.IdentitySelector(
|
|
135
|
+
identity=identity
|
|
136
|
+
),
|
|
137
|
+
access_selector=asset_v1.IamPolicyAnalysisQuery.AccessSelector(
|
|
138
|
+
roles=[role]
|
|
139
|
+
),
|
|
140
|
+
options=asset_v1.IamPolicyAnalysisQuery.Options(
|
|
141
|
+
expand_groups=expand_groups,
|
|
142
|
+
expand_roles=True,
|
|
143
|
+
)
|
|
144
|
+
)
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
try:
|
|
148
|
+
# Execute the analysis
|
|
149
|
+
logger.info(f"Checking if service account {service_account_email} has role {role} in project {project_id}")
|
|
150
|
+
response = client.analyze_iam_policy(request=request)
|
|
151
|
+
|
|
152
|
+
# Check if any results were returned
|
|
153
|
+
if response.main_analysis and response.main_analysis.analysis_results:
|
|
154
|
+
logger.info(f"Service account {service_account_email} has role {role} in project {project_id}")
|
|
155
|
+
return True
|
|
156
|
+
|
|
157
|
+
logger.info(f"Service account {service_account_email} does not have role {role} in project {project_id}")
|
|
158
|
+
return False
|
|
159
|
+
|
|
160
|
+
except Exception as e:
|
|
161
|
+
logger.exception(f"Error analyzing IAM policy: {e}")
|
|
162
|
+
raise
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def check_group_has_role_in_project(
|
|
166
|
+
project_id: str,
|
|
167
|
+
group_email: str,
|
|
168
|
+
organization_id: str,
|
|
169
|
+
role: str = "roles/owner",
|
|
170
|
+
expand_groups: bool = True
|
|
171
|
+
) -> bool:
|
|
172
|
+
"""
|
|
173
|
+
Check if a group has a specific role in a GCP project.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
project_id: GCP project ID (e.g., 'sky-starfi-mam-res-gcpro-1')
|
|
177
|
+
group_email: Email of the group to check (e.g., 'dev-team@gcporg.com')
|
|
178
|
+
organization_id: GCP organization ID (e.g., '111111111111')
|
|
179
|
+
role: Role to check (e.g., 'roles/owner', 'roles/editor')
|
|
180
|
+
expand_groups: Whether to expand group memberships (default: True)
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
bool: True if the group has the role in the project, False otherwise
|
|
184
|
+
|
|
185
|
+
Example:
|
|
186
|
+
>>> has_access = check_group_has_role_in_project(
|
|
187
|
+
... project_id='sky-starfi-mam-res-gcpro-1',
|
|
188
|
+
... group_email='dev-team@gcporg.com',
|
|
189
|
+
... organization_id='111111111111',
|
|
190
|
+
... role='roles/owner'
|
|
191
|
+
... )
|
|
192
|
+
"""
|
|
193
|
+
client = asset_v1.AssetServiceClient()
|
|
194
|
+
|
|
195
|
+
# Construct the full resource name
|
|
196
|
+
scope = f"organizations/{organization_id}"
|
|
197
|
+
full_resource_name = f"//cloudresourcemanager.googleapis.com/projects/{project_id}"
|
|
198
|
+
identity = f"group:{group_email}"
|
|
199
|
+
|
|
200
|
+
# Build the request
|
|
201
|
+
request = asset_v1.AnalyzeIamPolicyRequest(
|
|
202
|
+
analysis_query=asset_v1.IamPolicyAnalysisQuery(
|
|
203
|
+
scope=scope,
|
|
204
|
+
resource_selector=asset_v1.IamPolicyAnalysisQuery.ResourceSelector(
|
|
205
|
+
full_resource_name=full_resource_name
|
|
206
|
+
),
|
|
207
|
+
identity_selector=asset_v1.IamPolicyAnalysisQuery.IdentitySelector(
|
|
208
|
+
identity=identity
|
|
209
|
+
),
|
|
210
|
+
access_selector=asset_v1.IamPolicyAnalysisQuery.AccessSelector(
|
|
211
|
+
roles=[role]
|
|
212
|
+
),
|
|
213
|
+
options=asset_v1.IamPolicyAnalysisQuery.Options(
|
|
214
|
+
expand_groups=expand_groups,
|
|
215
|
+
expand_roles=True,
|
|
216
|
+
)
|
|
217
|
+
)
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
try:
|
|
221
|
+
# Execute the analysis
|
|
222
|
+
logger.info(f"Checking if group {group_email} has role {role} in project {project_id}")
|
|
223
|
+
response = client.analyze_iam_policy(request=request)
|
|
224
|
+
|
|
225
|
+
# Check if any results were returned
|
|
226
|
+
if response.main_analysis and response.main_analysis.analysis_results:
|
|
227
|
+
logger.info(f"Group {group_email} has role {role} in project {project_id}")
|
|
228
|
+
return True
|
|
229
|
+
|
|
230
|
+
logger.info(f"Group {group_email} does not have role {role} in project {project_id}")
|
|
231
|
+
return False
|
|
232
|
+
|
|
233
|
+
except Exception as e:
|
|
234
|
+
logger.exception(f"Error analyzing IAM policy: {e}")
|
|
235
|
+
raise
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def _get_all_service_projects(base_paths, prefix):
|
|
239
|
+
service_projects = []
|
|
240
|
+
|
|
241
|
+
for path in base_paths:
|
|
242
|
+
logger.info(f"[INFO] Searching for projects under: {path}")
|
|
243
|
+
|
|
244
|
+
for root, _, _ in os.walk(path):
|
|
245
|
+
if root == path:
|
|
246
|
+
continue
|
|
247
|
+
|
|
248
|
+
for _, _, projects in os.walk(root):
|
|
249
|
+
for project in projects:
|
|
250
|
+
if not project.endswith(".yaml"):
|
|
251
|
+
continue
|
|
252
|
+
if project.startswith(prefix):
|
|
253
|
+
service_projects.append(project.split('.')[0])
|
|
254
|
+
else:
|
|
255
|
+
service_projects.append(f"{prefix}-{project.split('.')[0]}")
|
|
256
|
+
|
|
257
|
+
return list(set(service_projects))
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def get_projects_with_role(
|
|
261
|
+
user_email: str,
|
|
262
|
+
organization_id: str,
|
|
263
|
+
role: str = "roles/owner",
|
|
264
|
+
expand_groups: bool = True,
|
|
265
|
+
project_prefix: Optional[str] = None,
|
|
266
|
+
projects_base_paths: Optional[list] = []
|
|
267
|
+
) -> list:
|
|
268
|
+
"""
|
|
269
|
+
Get all projects where a user or service account has a specific role.
|
|
270
|
+
Searches for all service projects in the organization.
|
|
271
|
+
|
|
272
|
+
Args:
|
|
273
|
+
user_email: Email of the user or service account to check
|
|
274
|
+
(e.g., 'oshasha10@gcporg.com' or 'my-sa@project.iam.gserviceaccount.com')
|
|
275
|
+
organization_id: GCP organization ID (e.g., '111111111111')
|
|
276
|
+
role: Role to check (e.g., 'roles/owner', 'roles/editor')
|
|
277
|
+
expand_groups: Whether to expand group memberships (default: True)
|
|
278
|
+
|
|
279
|
+
Returns:
|
|
280
|
+
list: List of project IDs where the user/service account has the specified role
|
|
281
|
+
|
|
282
|
+
Example:
|
|
283
|
+
>>> projects = get_projects_with_role(
|
|
284
|
+
... user_email='oshasha10@gcporg.com',
|
|
285
|
+
... organization_id='111111111111',
|
|
286
|
+
... role='roles/owner'
|
|
287
|
+
... )
|
|
288
|
+
"""
|
|
289
|
+
logger.info(f"Fetching all projects in organization {organization_id} (including folders)")
|
|
290
|
+
|
|
291
|
+
try:
|
|
292
|
+
all_projects = _get_all_service_projects(
|
|
293
|
+
base_paths=projects_base_paths,
|
|
294
|
+
prefix=project_prefix
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
logger.info(f"Found {len(all_projects)} total service project(s) across organization {organization_id}")
|
|
298
|
+
|
|
299
|
+
# Filter projects where user has the specified role
|
|
300
|
+
matching_projects = []
|
|
301
|
+
|
|
302
|
+
for project_id in all_projects:
|
|
303
|
+
# Check if user has the role in this project
|
|
304
|
+
if check_user_has_role_in_project(
|
|
305
|
+
project_id=project_id,
|
|
306
|
+
user_email=user_email,
|
|
307
|
+
organization_id=organization_id,
|
|
308
|
+
role=role,
|
|
309
|
+
expand_groups=expand_groups
|
|
310
|
+
):
|
|
311
|
+
matching_projects.append(project_id)
|
|
312
|
+
|
|
313
|
+
logger.info(f"Checked {len(all_projects)} projects, found {len(matching_projects)} where {user_email} has role {role}")
|
|
314
|
+
return sorted(matching_projects)
|
|
315
|
+
|
|
316
|
+
except Exception as e:
|
|
317
|
+
logger.exception(f"Error fetching projects: {e}")
|
|
318
|
+
raise
|
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
"""IAM access management utilities for GCP."""
|
|
2
|
-
|
|
3
|
-
import logging
|
|
4
|
-
import os
|
|
5
|
-
import google.cloud.logging
|
|
6
|
-
from google.cloud import asset_v1
|
|
7
|
-
from typing import Optional
|
|
8
|
-
|
|
9
|
-
# Initialize Google Cloud Logging
|
|
10
|
-
client = google.cloud.logging.Client()
|
|
11
|
-
client.setup_logging()
|
|
12
|
-
|
|
13
|
-
# Configure the logger
|
|
14
|
-
logger = logging.getLogger("uvicorn")
|
|
15
|
-
logger.setLevel(logging.INFO)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def _get_identity_string(email: str) -> str:
|
|
19
|
-
"""
|
|
20
|
-
Helper function to construct the proper identity string.
|
|
21
|
-
Automatically detects if the email is a service account or user.
|
|
22
|
-
|
|
23
|
-
Args:
|
|
24
|
-
email: Email address (user or service account)
|
|
25
|
-
|
|
26
|
-
Returns:
|
|
27
|
-
str: Properly formatted identity string
|
|
28
|
-
"""
|
|
29
|
-
if ".gserviceaccount.com" in email.lower():
|
|
30
|
-
return f"serviceAccount:{email}"
|
|
31
|
-
else:
|
|
32
|
-
return f"user:{email}"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def check_user_has_role_in_project(
|
|
36
|
-
project_id: str,
|
|
37
|
-
user_email: str,
|
|
38
|
-
organization_id: str,
|
|
39
|
-
role: str = "roles/owner",
|
|
40
|
-
expand_groups: bool = True
|
|
41
|
-
) -> bool:
|
|
42
|
-
"""
|
|
43
|
-
Check if a user or service account has a specific role in a GCP project.
|
|
44
|
-
|
|
45
|
-
Args:
|
|
46
|
-
user_email: Email of the user or service account to check
|
|
47
|
-
(e.g., 'oshasha10@gcporg.com' or 'my-sa@project.iam.gserviceaccount.com')
|
|
48
|
-
role: Role to check (e.g., 'roles/owner', 'roles/editor')
|
|
49
|
-
project_id: GCP project ID (e.g., 'sky-starfi-mam-res-gcpro-1')
|
|
50
|
-
organization_id: GCP organization ID (e.g., '111111111111')
|
|
51
|
-
expand_groups: Whether to expand group memberships (default: True)
|
|
52
|
-
|
|
53
|
-
Returns:
|
|
54
|
-
bool: True if the user/service account has the role in the project, False otherwise
|
|
55
|
-
|
|
56
|
-
Example:
|
|
57
|
-
>>> has_access = check_user_has_role_in_project(
|
|
58
|
-
... user_email='oshasha10@gcporg.com',
|
|
59
|
-
... role='roles/owner',
|
|
60
|
-
... project_id='sky-starfi-mam-res-gcpro-1',
|
|
61
|
-
... )
|
|
62
|
-
"""
|
|
63
|
-
client = asset_v1.AssetServiceClient()
|
|
64
|
-
|
|
65
|
-
# Construct the full resource name
|
|
66
|
-
scope = f"organizations/{organization_id}"
|
|
67
|
-
full_resource_name = f"//cloudresourcemanager.googleapis.com/projects/{project_id}"
|
|
68
|
-
identity = _get_identity_string(user_email)
|
|
69
|
-
|
|
70
|
-
# Build the request
|
|
71
|
-
request = asset_v1.AnalyzeIamPolicyRequest(
|
|
72
|
-
analysis_query=asset_v1.IamPolicyAnalysisQuery(
|
|
73
|
-
scope=scope,
|
|
74
|
-
resource_selector=asset_v1.IamPolicyAnalysisQuery.ResourceSelector(
|
|
75
|
-
full_resource_name=full_resource_name
|
|
76
|
-
),
|
|
77
|
-
identity_selector=asset_v1.IamPolicyAnalysisQuery.IdentitySelector(
|
|
78
|
-
identity=identity
|
|
79
|
-
),
|
|
80
|
-
access_selector=asset_v1.IamPolicyAnalysisQuery.AccessSelector(
|
|
81
|
-
roles=[role]
|
|
82
|
-
),
|
|
83
|
-
options=asset_v1.IamPolicyAnalysisQuery.Options(
|
|
84
|
-
expand_groups=expand_groups,
|
|
85
|
-
expand_roles=True,
|
|
86
|
-
# expand_resources=True
|
|
87
|
-
)
|
|
88
|
-
)
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
try:
|
|
92
|
-
# Execute the analysis
|
|
93
|
-
logger.info(f"Checking if {user_email} has role {role} in project {project_id}")
|
|
94
|
-
response = client.analyze_iam_policy(request=request)
|
|
95
|
-
|
|
96
|
-
# Check if any results were returned
|
|
97
|
-
# If the user has the role, there will be analysis results
|
|
98
|
-
if response.main_analysis and response.main_analysis.analysis_results:
|
|
99
|
-
logger.info(f"{user_email} has role {role} in project {project_id}")
|
|
100
|
-
return True
|
|
101
|
-
|
|
102
|
-
logger.info(f"{user_email} does not have role {role} in project {project_id}")
|
|
103
|
-
return False
|
|
104
|
-
|
|
105
|
-
except Exception as e:
|
|
106
|
-
logger.exception(f"Error analyzing IAM policy: {e}")
|
|
107
|
-
raise
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def _get_all_service_projects(base_paths, prefix):
|
|
111
|
-
service_projects = []
|
|
112
|
-
|
|
113
|
-
for path in base_paths:
|
|
114
|
-
logger.info(f"[INFO] Searching for projects under: {path}")
|
|
115
|
-
|
|
116
|
-
for root, _, _ in os.walk(path):
|
|
117
|
-
if root == path:
|
|
118
|
-
continue
|
|
119
|
-
|
|
120
|
-
for _, _, projects in os.walk(root):
|
|
121
|
-
for project in projects:
|
|
122
|
-
if not project.endswith(".yaml"):
|
|
123
|
-
continue
|
|
124
|
-
if project.startswith(prefix):
|
|
125
|
-
service_projects.append(project.split('.')[0])
|
|
126
|
-
else:
|
|
127
|
-
service_projects.append(f"{prefix}-{project.split('.')[0]}")
|
|
128
|
-
|
|
129
|
-
return list(set(service_projects))
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
def get_projects_with_role(
|
|
133
|
-
user_email: str,
|
|
134
|
-
organization_id: str,
|
|
135
|
-
role: str = "roles/owner",
|
|
136
|
-
expand_groups: bool = True,
|
|
137
|
-
project_prefix: Optional[str] = None,
|
|
138
|
-
projects_base_paths: Optional[list] = []
|
|
139
|
-
) -> list:
|
|
140
|
-
"""
|
|
141
|
-
Get all projects where a user or service account has a specific role.
|
|
142
|
-
Searches for all service projects in the organization.
|
|
143
|
-
|
|
144
|
-
Args:
|
|
145
|
-
user_email: Email of the user or service account to check
|
|
146
|
-
(e.g., 'oshasha10@gcporg.com' or 'my-sa@project.iam.gserviceaccount.com')
|
|
147
|
-
organization_id: GCP organization ID (e.g., '111111111111')
|
|
148
|
-
role: Role to check (e.g., 'roles/owner', 'roles/editor')
|
|
149
|
-
expand_groups: Whether to expand group memberships (default: True)
|
|
150
|
-
|
|
151
|
-
Returns:
|
|
152
|
-
list: List of project IDs where the user/service account has the specified role
|
|
153
|
-
|
|
154
|
-
Example:
|
|
155
|
-
>>> projects = get_projects_with_role(
|
|
156
|
-
... user_email='oshasha10@gcporg.com',
|
|
157
|
-
... organization_id='111111111111',
|
|
158
|
-
... role='roles/owner'
|
|
159
|
-
... )
|
|
160
|
-
"""
|
|
161
|
-
logger.info(f"Fetching all projects in organization {organization_id} (including folders)")
|
|
162
|
-
|
|
163
|
-
try:
|
|
164
|
-
all_projects = _get_all_service_projects(
|
|
165
|
-
base_paths=projects_base_paths,
|
|
166
|
-
prefix=project_prefix
|
|
167
|
-
)
|
|
168
|
-
|
|
169
|
-
logger.info(f"Found {len(all_projects)} total service project(s) across organization {organization_id}")
|
|
170
|
-
|
|
171
|
-
# Filter projects where user has the specified role
|
|
172
|
-
matching_projects = []
|
|
173
|
-
|
|
174
|
-
for project_id in all_projects:
|
|
175
|
-
# Check if user has the role in this project
|
|
176
|
-
if check_user_has_role_in_project(
|
|
177
|
-
project_id=project_id,
|
|
178
|
-
user_email=user_email,
|
|
179
|
-
organization_id=organization_id,
|
|
180
|
-
role=role,
|
|
181
|
-
expand_groups=expand_groups
|
|
182
|
-
):
|
|
183
|
-
matching_projects.append(project_id)
|
|
184
|
-
|
|
185
|
-
logger.info(f"Checked {len(all_projects)} projects, found {len(matching_projects)} where {user_email} has role {role}")
|
|
186
|
-
return sorted(matching_projects)
|
|
187
|
-
|
|
188
|
-
except Exception as e:
|
|
189
|
-
logger.exception(f"Error fetching projects: {e}")
|
|
190
|
-
raise
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gcp_platforms_auto-0.8.3 → gcp_platforms_auto-0.8.4}/gcp_platforms_auto.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{gcp_platforms_auto-0.8.3 → gcp_platforms_auto-0.8.4}/gcp_platforms_auto.egg-info/requires.txt
RENAMED
|
File without changes
|
{gcp_platforms_auto-0.8.3 → gcp_platforms_auto-0.8.4}/gcp_platforms_auto.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|