36
36
runtime_region = os .getenv ('AWS_REGION' )
37
37
ic_bucket_name = os .getenv ('IC_S3_BucketName' )
38
38
s3 = boto3 .resource ('s3' )
39
- orgs_client = boto3 .client ('organizations' , region_name = runtime_region , config = AWS_CONFIG )
39
+ orgs_client = boto3 .client (
40
+ 'organizations' , region_name = runtime_region , config = AWS_CONFIG )
40
41
ic_admin = boto3 .client (
41
42
'sso-admin' , region_name = runtime_region , config = AWS_CONFIG )
42
43
ic_instance_arn = os .getenv ('IC_InstanceArn' )
@@ -107,6 +108,7 @@ def log_and_append_error(message):
107
108
108
109
CACHE_TTL = 1800 # 30 minutes
109
110
111
+
110
112
class CacheManager :
111
113
def __init__ (self ):
112
114
self ._cache = {}
@@ -198,7 +200,8 @@ def execute_with_retry(func, *args, **kwargs):
198
200
base_delay = RETRY_BASE_DELAY * (2 ** attempt )
199
201
sleep (base_delay + random .uniform (0 , 1 ))
200
202
except Exception as error :
201
- log_and_append_error (f"Unexpected error in { func .__name__ } : { str (error )} " )
203
+ log_and_append_error (
204
+ f"Unexpected error in { func .__name__ } : { str (error )} " )
202
205
raise
203
206
204
207
@@ -209,6 +212,7 @@ def process_permission_set(local_perm_set, aws_permission_sets):
209
212
local_description = local_perm_set .get ('Description' , '' )
210
213
local_session_duration = local_perm_set .get (
211
214
'Session_Duration' , default_session_duration )
215
+ local_tags = local_perm_set .get ('Tags' , [])
212
216
213
217
# Check if this permission set should be skipped
214
218
global skipped_perm_set
@@ -222,7 +226,6 @@ def process_permission_set(local_perm_set, aws_permission_sets):
222
226
logger .info (f"Permission set { perm_set_name } exists. Syncing." )
223
227
perm_set_arn = aws_permission_sets [perm_set_name ]['Arn' ]
224
228
aws_session_duration = aws_permission_sets [perm_set_name ]['SessionDuration' ]
225
- local_tags = local_perm_set .get ('Tags' , [])
226
229
aws_description = aws_permission_sets [perm_set_name ]['Description' ]
227
230
else :
228
231
# Create new permission set
@@ -321,10 +324,11 @@ def is_provisioned_or_outdated(perm_set_name, perm_set_arn, account):
321
324
try :
322
325
# Check never provisioned
323
326
provisioned = []
324
- paginator = ic_admin .get_paginator ('list_permission_sets_provisioned_to_account' )
325
- for page in paginator .paginate (InstanceArn = ic_instance_arn ,AccountId = account ):
327
+ paginator = ic_admin .get_paginator (
328
+ 'list_permission_sets_provisioned_to_account' )
329
+ for page in paginator .paginate (InstanceArn = ic_instance_arn , AccountId = account ):
326
330
provisioned .extend (page .get ('PermissionSets' , []))
327
-
331
+
328
332
if provisioned :
329
333
if perm_set_arn not in provisioned :
330
334
return (perm_set_name , perm_set_arn , account , 'never_provisioned' )
@@ -340,7 +344,8 @@ def is_provisioned_or_outdated(perm_set_name, perm_set_arn, account):
340
344
return (perm_set_name , perm_set_arn , account , 'outdated' )
341
345
342
346
except Exception as error :
343
- log_and_append_error (f"Status check failed for { account } : { str (error )} " )
347
+ log_and_append_error (
348
+ f"Status check failed for { account } : { str (error )} " )
344
349
logger .debug (f"No provisioning required for { perm_set_name } " )
345
350
return None
346
351
@@ -360,7 +365,8 @@ def provisioning_job():
360
365
try :
361
366
provision_account (perm_set_name , perm_set_arn , account )
362
367
except Exception as error :
363
- log_and_append_error (f"Failed to provision { account } : { str (error )} " )
368
+ log_and_append_error (
369
+ f"Failed to provision { account } : { str (error )} " )
364
370
365
371
if idx < len (provisioning_tasks ):
366
372
time .sleep (3 )
@@ -455,17 +461,21 @@ def deprovisioning_job(permission_sets):
455
461
if result : # If deprovisioning is required
456
462
confirmed_tasks .extend (result )
457
463
except Exception as error :
458
- log_and_append_error (f"Deprovisioning check failed: { error } " )
464
+ log_and_append_error (
465
+ f"Deprovisioning check failed: { error } " )
459
466
# if not confirmed_tasks:
460
467
# logger.info("No permission sets require deprovisioning")
461
468
# return
462
- deprovisioning_needed = [(name , arn , account ) for name , arn , account in confirmed_tasks if account is not None ]
463
- deletion_only = [(name , arn ) for name , arn , account in confirmed_tasks if account is None ]
469
+ deprovisioning_needed = [(name , arn , account ) for name ,
470
+ arn , account in confirmed_tasks if account is not None ]
471
+ deletion_only = [(name , arn ) for name , arn ,
472
+ account in confirmed_tasks if account is None ]
464
473
465
474
if not deprovisioning_needed :
466
475
logger .info ("No permission sets require deprovisioning" )
467
476
if deprovisioning_needed :
468
- logger .info (f"Starting deprovisioning of { len (deprovisioning_needed )} tasks" )
477
+ logger .info (
478
+ f"Starting deprovisioning of { len (deprovisioning_needed )} tasks" )
469
479
# Process in batches of 10
470
480
for i in range (0 , len (deprovisioning_needed ), 10 ):
471
481
batch = deprovisioning_needed [i :i + 10 ]
@@ -491,7 +501,8 @@ def deprovisioning_job(permission_sets):
491
501
if success :
492
502
deprovisioned_sets .add ((name , arn ))
493
503
except Exception as error :
494
- log_and_append_error (f"Deprovisioning failed: { error } " )
504
+ log_and_append_error (
505
+ f"Deprovisioning failed: { error } " )
495
506
496
507
if i + 10 < len (deprovisioning_needed ):
497
508
time .sleep (2 )
@@ -533,7 +544,7 @@ def deprovision_account(perm_set_arn, perm_set_name, account):
533
544
assignments = []
534
545
paginator = ic_admin .get_paginator ('list_account_assignments' )
535
546
for page in paginator .paginate (InstanceArn = ic_instance_arn , AccountId = account , PermissionSetArn = perm_set_arn
536
- )['AccountAssignments' ]:
547
+ )['AccountAssignments' ]:
537
548
assignments .extend (page .get ('AccountAssignments' , []))
538
549
539
550
for assignment in assignments :
@@ -822,30 +833,6 @@ def get_all_json_files(bucket_name):
822
833
return file_contents
823
834
824
835
825
- def create_permission_set (name , desc , tags , session_duration ):
826
- """Create a permission set in AWS IAM Identity Center"""
827
- logger .info (f"Creating permission set: { name } " )
828
- try :
829
- response = ic_admin .create_permission_set (
830
- Name = name ,
831
- Description = desc ,
832
- InstanceArn = ic_instance_arn ,
833
- SessionDuration = session_duration ,
834
- Tags = tags
835
- )
836
- except ic_admin .exceptions .ConflictException as error :
837
- logger .info ("%sThe same IAM Identity Center process may have been started in another invocation, or check for potential conflicts; skipping..." , error )
838
- sleep (0.5 )
839
- except ClientError as error :
840
- error_message = f'Client error occurred: { error } '
841
- log_and_append_error (error_message )
842
- except Exception as error :
843
- error_message = f'Error occurred: { error } '
844
- log_and_append_error (error_message )
845
- cache .set (f"permsets_{ delegated } " , None )
846
- return response
847
-
848
-
849
836
def add_managed_policy_to_perm_set (local_name , perm_set_arn , managed_policy_arn ):
850
837
"""Attach a managed policy to a permission set"""
851
838
logger .info (
@@ -1300,7 +1287,8 @@ def sync_tags(local_name, local_tags, perm_set_arn):
1300
1287
def is_account_active (account_id ):
1301
1288
"""Check if the AWS account is active (not suspended or pending closure)"""
1302
1289
try :
1303
- response = execute_with_retry (orgs_client .describe_account ,AccountId = account_id )
1290
+ response = execute_with_retry (
1291
+ orgs_client .describe_account , AccountId = account_id )
1304
1292
if response ['Account' ]['Status' ] == 'ACTIVE' :
1305
1293
return True
1306
1294
except Exception as error :
0 commit comments